Nikola Schou Nikola Schou - 1 month ago 12
Node.js Question

Auth0 authentication of single-page-app on a different domain than the api

I'm trying add Auth0 authentication to my single-page-app. My app is running under a domain, say app.mycompany.com, whereas the api used by this app is running under a different domain, say api.mycompany.com.

I'm aware of this thread:

Single Sign On (SSO) solution/architecture for Single Page App (SPA)

and the auth0 articles and github repositories linked by here. But I have a feeling that my scenario is slightly simpler, as I don't necessarily want to have single-sign-on between several different single-page-apps. For a start I just want the seperation between the API and the app.

Here is what I have tried already:

I already started from the article React Login With Auth0 and downloaded the starter project. I can surely login without problems and it will leave me with an id_token in my localStorage containing a JWS issued by Auth0.

I can also login directly on api.mycompany.com (my FeathersJS API application) and I can see that during the OAuth redirecting process, the id_token token is magically translated to a feathers-jwt token issued by my Feathers application containing the internal ID of the user-object matching the auth0-ID. I also have implemented the logic used to map from the Auth0-ID to my internal ID. Furthermore all my Feathers hooks such as validation of token and population of the user are working.

What I cannot figure out is how to alter the react-application running under app.mycompany.com with an Auth0-token in localStorage, so that this token is translated to a feathers-jwt token by api.mycompany.com, in such a way that all succeeding API-calls automatically has the feathers-jwt token included so the API can validate the user and return the right data.

Any suggestions on how to proceed will be greatly appreciated.

A couple of more background details:


  • The api is built on node.js and featherjs (which basically is an extension of Express)

  • The single-page-app is built on ReactJS and is served by a simple Express server, but it could be served by any server that can serve static files over http. The single-page-app makes http-requests to the api to read data and perform operations.

  • The api has the following lines of code taking care of the authentication:

    const authentication = require('feathers-authentication');
    const Auth0Strategy = require('passport-auth0').Strategy;
    app.configure(authentication({
    local:false,
    token: {
    secret: 'mysecret',
    payload: ['email', 'auth0Nickname'],
    issuer: 'mycompany'
    },
    idField: 'id',
    shouldSetupSuccessRoute: false,
    auth0: {
    strategy: Auth0Strategy,
    domain: 'mycompany.eu.auth0.com',
    'clientID': 'xxx',
    'clientSecret': 'yyy'
    }


    }));


Answer

If you haven't done so, you should follow this article (React Login with Auth0) to implement the authentication on your React application. If you already tried to follow it, update your question with specific issues you faced.

Even though you currently not need SSO, the actual implementation of the authentication in your application will not vary much. By using Auth0 enabling SSO across your apps is mostly enabling configuration switches.

Finally for a full reference with all the theory behind the security related aspects of your exact scenario check:

Auth0 Architecture Scenarios: SPA + API


Update:

The full scenario I linked too covers the most comprehensive scenarios where an API is accessed by a multitude of client applications that may even be developed by third-parties that do not own the protected API, but want to access the data behind it.

It does this by leveraging recent features that are currently only available in the US region and that at a very high level can be described as an OAuth 2.0 authorization server delivered as a service.

Your particular scenario is simpler, both the API and client application are under control of the same entity, so you have another option.

Option 1 - Leverage the API authorization through Auth0 US region only (for now)

In this situation your client application, at authentication time, would receive an id_token that would be used to know the currently authenticated user and would also receive an access_token that could be used to call the API on behalf of the authenticated user.

This makes a clear separation between the client application and the API; the id_token is for client application usage and the access_token for API usage.

It has the benefit that authorization is clearly separated from authentication and you can have a very fine-grained control over authorization decisions by controlling the scopes included in the access token.

Option 2 - Authenticate in client application and API in the same way

You can deploy your client application and API separately, but still treat them from a conceptual perspective as the same application (you would have one client configured in Auth0 representing both client-side and API).

This has the benefit that you could use the id_token that is obtained after authentication completes to know who the user was on the client-side and also as the mechanism to authenticate each API request.

You would have to configure feathers API to validate the Auth0 id_token as an accepted token for accessing the API. This means that you don't use any feathers based on authentication on the API, that is, you just accept tokens issued by Auth0 to your application as the way to validate the access.