Sign users in
Send a person to the NoCFO login page, then call the API as that person.
Use this when your own product signs a NoCFO user in and then calls the API as them. A normal OAuth library does the hard parts. AppAuth, openid-client, Spring Security, and Expo AuthSession all work, and so does any other library that speaks OAuth 2.0 and OpenID Connect.
You give the library the settings below. It handles the browser login and hands you tokens. A personal access token, from the quick start, is a different credential for a server you control.
How login works
- Your app sends the user to the NoCFO login page in the browser.
- They sign in and approve access. NoCFO sends the browser back to your app with a one-time code.
- Your app trades that code for two tokens. One is for API calls. The other is for getting a new API token later, without asking the user to log in again.
- Call the API with the first token. When it expires, use the second token to get a fresh one.
Trade the code in within one minute. It stops working after that, and it can only be used once.
Ask NoCFO to register the app
NoCFO creates the registration. Send the details with the client request.
Say which kind of app it is:
- A mobile app, or a website whose code runs in the browser, cannot keep a secret. Tell NoCFO it is public.
- A server can keep a secret. Tell NoCFO it is confidential. You will get a client secret as well as a client id. Leave that secret on the server. Do not put it in a mobile app or in JavaScript that ships to the browser.
Also send the exact address NoCFO should return the user to after login, and say whether you need testing, production, or both. Testing and production are registered separately. A testing client id does not work in production.
The return address has to match the registered one character for character. A different port, a different path, or http instead of https is a different address, and login fails.
Where to send people, and where to call the API
Login and the API are on different hosts. The OAuth library talks to the login host. Your API calls go to the API host.
| Login | API | |
|---|---|---|
| Testing | https://login-tst.nocfo.io | https://api-tst.nocfo.io |
| Production | https://login.nocfo.io | https://api.nocfo.io |
Libraries call the login settings a discovery URL. It is a public page that lists the real login and token addresses, so you do not hardcode them:
- Testing: login-tst.nocfo.io/.well-known/openid-configuration
- Production: login.nocfo.io/.well-known/openid-configuration
Use the page that matches the client id you were given.
What to put in the library
| Setting | Value |
|---|---|
| Discovery URL | The login settings page above |
| Client id | The id NoCFO sent you |
| Redirect URI | The return address you registered, exactly |
| Response type | code |
| Scopes | openid profile email offline_access |
| PKCE | On. The method is S256 |
| Client authentication | No secret: none. With a secret: client_secret_post |
The scopes are one line, with spaces between the words. offline_access is the word that makes NoCFO give you a refresh token. Include it.
PKCE is a check that the app which started login is the same app that trades in the code. Turn it on for every app. It is required when the app has no secret.
If you have a client secret, the library must send it in the body of the token request. That method is called client_secret_post. If you have no secret, the method is none.
If the browser comes back with error=invalid_scope, the scope list does not match this registration. Change the list to the one NoCFO enabled, or email dev@nocfo.io. Sending the same list again will keep failing.
The tokens you get back
A successful login looks like this:
{
"access_token": "...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "...",
"id_token": "..."
}The access token is what you send on API calls. It lasts 60 minutes. expires_in is that lifetime in seconds.
The refresh token gets you a new access token. It lasts until NoCFO cancels it, or until a refresh replaces it. When a refresh returns a new refresh token, save the new one and stop using the old one.
The ID token names the user. You do not need it for API calls. It lasts 5 minutes.
"token_type": "Bearer" is only a label in this JSON. The next section shows the header the API actually accepts.
Keep the tokens somewhere safe, and do not write them to logs.
Call the API
Send the access token on the Authorization header, with the word Token, a space, and then the token.
curl --fail-with-body \
'https://api-tst.nocfo.io/v1/user/' \
-H 'Authorization: Token <access_token>' \
-H 'Accept: application/json'If you send Bearer instead, NoCFO ignores the header and answers 401, the same as if you had sent nothing.
You can add x-nocfo-client: your-app/1.0 so the call names your integration. That header is optional.
A 401 means the access token is missing, expired, or for the other environment. Refresh once and retry the same call. A 403 means this user is signed in and still not allowed to see that record. A new token will not change that.
The token acts as the person who logged in. To work in one of their companies, read the company id (slug) from the business list. Other calls are in the API reference. Testing and production reference manuals are on Environments.
Get a new access token
The library usually does this when the access token is about to expire. To do it yourself, post to the token address on the login host. This example is testing:
curl --fail-with-body \
-X POST 'https://login-tst.nocfo.io/identity/o/api/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'client_id=<client_id>' \
--data-urlencode 'refresh_token=<refresh_token>'If NoCFO gave you a client secret, send that too, as client_secret.
Save the new access token. If the response includes a refresh token, save that and discard the previous one. If the refresh fails, delete the saved tokens and send the user through login again.
In production, take the token address from the production login settings page. Do not keep using the testing address above.
Checklist
- Get a client id from NoCFO, and a client secret if the app runs on a server.
- Put the discovery URL, PKCE, and the scopes into your OAuth library.
- Sign in once and save the access token and the refresh token.
- Call the API with
Authorization: Token. - Refresh before the access token expires, and keep the newest refresh token.
- When the user logs out, delete the tokens you stored.
Look after the tokens
Use https for the return address. http is fine only on your own machine, at localhost, while you develop. The address still has to match what you registered.
Apps that cannot hide a secret must use PKCE. A client secret stays on the server. A refresh token is as sensitive as a password, because it keeps working until it is replaced or cancelled.
Do not log the one-time code, the access token, the refresh token, the client secret, or the PKCE value the library created for that login.
If you get stuck
Email dev@nocfo.io. Say whether this is testing or production, and include the client id, the return address, and the error text. Take tokens and secrets out of that text before you send it.
- Testing API docs: api-tst.nocfo.io/docs
- Production API docs: api.nocfo.io/docs