How to exchange OAuth2 authorization codes for access tokens received from a client (Ember) in Express?

322 views Asked by At

I'm using ember-simple-auth and torii to handle client-side OAuth2 authentication against Facebook and Google in an Ember app I'm building. I receive an authorization code from that process.

I want to send that code from the client to my REST API and exchange them for access tokens to get their user ID so I can figure out what information they should have access to.

Then, I want to put the user ID into a JSON web token that the client can send me in subsequent requests for data from the BE app.

My Problem: All examples I've found of using Passport for OAuth2 authentication rely on redirecting the user on the server side and using callbacks rather than just exchanging an already-provided authorization code.

What am I missing? This seems like something many apps would need to do.

1

There are 1 answers

2
João Angelo On

Assuming a compliant OAuth 2.0 implementation, exchanging an authorization code for an access token is accomplished by performing a POST request to the token endpoint URL and providing the following parameters using the application/x-www-form-urlencoded format:

  • grant_type - Must be set to authorization_code.
  • code - Will contain the value of the code you have.
  • redirect_uri - Must be included and the value match, if it was also included in the request to obtain the authorization code.

Additionally, depending on the client you'll have to either provide the client_id parameter if the client was not issued credentials or if the client has credentials you need to perform client authentication, which can be done by passing an HTTP Basic authentication header containing the identifier and the secret.

An example, using unirest, but easily adapted to other HTTP clients:

unirest.post(tokenEndpointUrl)
    .headers({
        'Accept': 'application/json',
        'Content-type': 'application/x-www-form-urlencoded'
    })
    .auth({
        user: clientId,
        pass: clientSecret
    })
    .send(`redirect_uri=${redirectUrl}`)
    .send(`code=${code}`)
    .send('grant_type=authorization_code')
    .end(function (response) {
        // Handle response
    });

Although the fundamentals will probably not change, check each provider documentation, because they may have extensions put in place or be more flexible in how you can provide the info. For example Auth0 and I think Google is the same will also allow you pass the parameters in a JSON encoded body instead of just in application/x-www-form-urlencoded format.


Update:

Specific authentication providers may implement additional libraries that simplify things for developers integrating with them. For example, Auth0 provides you with passport-auth0 that abstracts and simplifies the way you can integrate Auth0 authentication into your application.