Authentication Management
Setup MFA
An account can be more secure by setting if 2FA authentication. 2FA can be enabled using the authentication API's create method (setupMFA action)
Change sign in identity (email or mobileNo)
An account's login identity (email and/or mobileNo) can only be changed using the authentication API's create method (changeIdentity action). It will then send a Confirm Change Identity email that will contain a code that should be applied using the (authentication API)[https://developers.example.com/docs/api#authentication]'s create method (applyActionCode action)
Change password
An account's password can only be changed using the authentication API's create method (changePassword action). It will then send a Confirm Password Change email that will contain a code that should be applied using the authentication API's create method (applyActionCode action)
Facebook Login
When a user is logged in with Facebook, they will then be redirected back to your app.
Create a route in your app such as
https://www.example.com/authenticate/facebook/
- this should be an Valid OAuth Redirect URIs in the associated facebook app
Facebook will redirect users to this route after they login.
Now it’s time for the good bit, we are going to start logging in your users with Facebook. All we need to do here is append a few parameters to the Facebook login url. When our users click a button or link, we will send them to this url. To make things easier
javascript// state can be used for persisting state across the session // this will be passed to the redirectURI as a query parameter including the needed code // NOTE: you can also use JSON instead of URLSearchParams // as this is only to give structure for easier parsing const state = window.btoa(new URLSearchParams(window.location.search)) // compose the query paramets for the facebook oauth dialog const queryParams = new URLSearchParams({ client_id: '<facebook-client-id>', redirect_uri: [window.location.href.split('?')[0], 'oauth', 'facebook'].join('/'), scope: 'email', state, }).toString(); const oauthURI = 'https://www.facebook.com/v10.0/dialog/oauth?' + queryParams;
// state can be used for persisting state across the session // this will be passed to the redirectURI as a query parameter including the needed code // NOTE: you can also use JSON instead of URLSearchParams // as this is only to give structure for easier parsing const state = window.btoa(new URLSearchParams(window.location.search)) // compose the query paramets for the facebook oauth dialog const queryParams = new URLSearchParams({ client_id: '<facebook-client-id>', redirect_uri: [window.location.href.split('?')[0], 'oauth', 'facebook'].join('/'), scope: 'email', state, }).toString(); const oauthURI = 'https://www.facebook.com/v10.0/dialog/oauth?' + queryParams;
As mentioned before, once your users login, they will be redirected back to your app. The url they are redirect to will contain a special code. For example:
shhttps://www.example.com/authenticate/facebook?code=CODE_IS_HERE
https://www.example.com/authenticate/facebook?code=CODE_IS_HERE
Get the code from the url (optionally parse the state if needed)
javascriptconst code = new URLSearchParams(location.search).get('code') const state = new URLSearchParams(location.search).get('state') const parsedState = new URLSearchParams(window.atob(state));
const code = new URLSearchParams(location.search).get('code') const state = new URLSearchParams(location.search).get('state') const parsedState = new URLSearchParams(window.atob(state));
And use it to authenticate (and be registered if not yet) to the server
shPOST /authentication \ -H 'Content-Type:application/json' \ -d '{ "strategy": "facebook", # NOTE: for some reason facebook requires the redirectURI to end in a slash "redirectURI": "<should be the same as the one used to create the oauthURI>", "code": "<code received>" }'
POST /authentication \ -H 'Content-Type:application/json' \ -d '{ "strategy": "facebook", # NOTE: for some reason facebook requires the redirectURI to end in a slash "redirectURI": "<should be the same as the one used to create the oauthURI>", "code": "<code received>" }'
Google Login
When a user is logged in with Google, they will then be redirected back to your app.
Create a route in your app such as
https://www.example.com/authenticate/google/
- this should be an Valid OAuth Redirect URIs in the associated google oAuth client
Google will redirect users to this route after they login.
Now it’s time for the good bit, we are going to start logging in your users with Google. All we need to do here is append a few parameters to the Google login url. When our users click a button or link, we will send them to this url. To make things easier
javascript// state can be used for persisting state across the session // this will be passed to the redirectURI as a query parameter including the needed code const state = window.btoa(new URLSearchParams(window.location.search)) // compose the query paramets for the google oauth dialog const queryParams = new URLSearchParams({ client_id: '<google-client-id>', redirect_uri: 'http://localhost:8080', // this is important as if abset, the facebook user's email will not be fetched scope: [ 'https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile', ].join(' '), response_type: 'code', access_type: 'offline', prompt: 'consent', state, }).toString(); const oauthURI = 'https://accounts.google.com/o/oauth2/v2/auth?' + queryParams;
// state can be used for persisting state across the session // this will be passed to the redirectURI as a query parameter including the needed code const state = window.btoa(new URLSearchParams(window.location.search)) // compose the query paramets for the google oauth dialog const queryParams = new URLSearchParams({ client_id: '<google-client-id>', redirect_uri: 'http://localhost:8080', // this is important as if abset, the facebook user's email will not be fetched scope: [ 'https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile', ].join(' '), response_type: 'code', access_type: 'offline', prompt: 'consent', state, }).toString(); const oauthURI = 'https://accounts.google.com/o/oauth2/v2/auth?' + queryParams;
As mentioned before, once your users login, they will be redirected back to your app. The url they are redirect to will contain a special code. For example:
shhttps://www.example.com/authenticate/google?code=CODE_IS_HERE
https://www.example.com/authenticate/google?code=CODE_IS_HERE
Get the code from the url
javascriptconst code = new URLSearchParams(location.search).get('code') const state = new URLSearchParams(location.search).get('state') const parsedState = new URLSearchParams(window.atob(state));
const code = new URLSearchParams(location.search).get('code') const state = new URLSearchParams(location.search).get('state') const parsedState = new URLSearchParams(window.atob(state));
And use it to authenticate (and be registered if not yet) to the server
shPOST /authentication \ -H 'Content-Type:application/json' \ -d '{ "strategy": "google", "redirectURI": "<should be the same as the one used to create the oauthURI>", "code": "<code received>" }'
POST /authentication \ -H 'Content-Type:application/json' \ -d '{ "strategy": "google", "redirectURI": "<should be the same as the one used to create the oauthURI>", "code": "<code received>" }'
Linking OAuth Accounts to Existing Accounts
OAuth accounts from supported providers (google, facebook) can be linked to an existing account by using the connectOAuthAccount
action flow
login to the relevant user and store the accessToken for later usage
shPOST /authentication -d '{ "email": "email@domain.com", "password": "strongpassword" }' # responds with # { accessToken: 'ey***.***.***' }
POST /authentication -d '{ "email": "email@domain.com", "password": "strongpassword" }' # responds with # { accessToken: 'ey***.***.***' }
trigger the
connectOAuthAccount
authentication action using the previous step's access token and store the resulting codde for later usageshPOST /authentication -H 'Authorization: Bearer <accessToken>' -d '{ "action": "connectOAuthAccount", "provider": "google", # or facebook }' # responds with # { code: 'some-action-code' }
POST /authentication -H 'Authorization: Bearer <accessToken>' -d '{ "action": "connectOAuthAccount", "provider": "google", # or facebook }' # responds with # { code: 'some-action-code' }
use the facebook/google login flow but add the previou's step's code in the state when composing the facebook/google oauth uri as it will be needed on the last step which is applying the
authentication code
in addition to the received oauth code instead of exchanging the oauth code for an accessToken by authenticatingjavascript// add the code in the previous step to the pre-encoded state // NOTE: you can also use JSON instead of URLSearchParams // as this is only to give structure for easier parsing const stateRaw = new URLSearchParams(window.location.search); stateRaw.append('code', 'some-action-code') const state = window.btoa(stateRaw); // compose the query paramets for the facebook oauth dialog const queryParams = new URLSearchParams({ state, // ... depends on the provider // ... use documentation above for reference }).toString(); const oauthURI = 'https://oauth-url?' + queryParams;
// add the code in the previous step to the pre-encoded state // NOTE: you can also use JSON instead of URLSearchParams // as this is only to give structure for easier parsing const stateRaw = new URLSearchParams(window.location.search); stateRaw.append('code', 'some-action-code') const state = window.btoa(stateRaw); // compose the query paramets for the facebook oauth dialog const queryParams = new URLSearchParams({ state, // ... depends on the provider // ... use documentation above for reference }).toString(); const oauthURI = 'https://oauth-url?' + queryParams;
Replace the last step from exchanging the oauth code to an accessToken to calling the
applyActionCode
actionjavascriptconst oauthCode = new URLSearchParams(location.search).get('code') const state = new URLSearchParams(location.search).get('state') const parsedState = new URLSearchParams(window.atob(state)); const actionCode = parsedState.get('code'); await http.post('/authentication', { headers: { Authorization: 'Bearer <accessToken>' }, body: { action: 'applyActionCode', code: actionCode, payload: { code: oauthCode, redirectURI: '<should be the same as the one used to create the oauthURI>', }, }, })
const oauthCode = new URLSearchParams(location.search).get('code') const state = new URLSearchParams(location.search).get('state') const parsedState = new URLSearchParams(window.atob(state)); const actionCode = parsedState.get('code'); await http.post('/authentication', { headers: { Authorization: 'Bearer <accessToken>' }, body: { action: 'applyActionCode', code: actionCode, payload: { code: oauthCode, redirectURI: '<should be the same as the one used to create the oauthURI>', }, }, })