Skip to content

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:

    sh
    https://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)

    javascript
    const 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

    sh
    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>"
    }'
    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:

    sh
    https://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

    javascript
    const 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

    sh
    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>"
    }'
    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

    sh
    POST /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 usage

    sh
    POST /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 authenticating

    javascript
      // 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 action

    javascript
    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>',
        },
      },
    })
    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>',
        },
      },
    })

Released under the MIT License.