Search code examples
oauth-2.0oautharchitecturejwtauth0

Auth0 flow in a fullstack system


I've got a react front end and a golang backend. I'm trying to incorporate Auth0 for user authentication/authorization. I'm a bit confused to how the flow is supposed to look like especially given to where the oauth callback should be. For instance:

  1. User clicks login in button
  2. User is redirected to the authorization server (say of google) where user logs in
  3. The callback url is called and depending on what I've given 2 things can happen:
    1. If I've provided a callback to my frontend, then the frontend does the token exhange (to obtain access/refresh) and then calls my backend so I update my db tables w/ my new user?
    2. If I've provided a callback to my backend, then my backend does the token exchange (to obtain access/refreshToken), saves the appropriate user tables for the new user and somehow (not sure how, redirect??) notifies the UI about the successful login and passes the access token
  4. Now the UI can use the access token to access protected resources on my backend for the given user

I'm really confused about points 3.1 and 3.2 and I cannot find any articles discussing this which makes me think I've got it all wrong... How does this usually work?


Solution

  • The Authorization Server redirects you to your page, which will happen in a browser. Let's say it will redirect you to https://myapp.example.com/callback. Now, in fact, it doesn't matter whether your frontend or backend will handle this page. As it's the browser that handled the redirect, you can always respond to the user by sending back a response to the browser.

    Here are the possible scenarios.

    1. Redirect to frontend.

    The frontend app will get the authorization code that's needed to get the access token (it will read it from the URL params of the redirect URI). Now, the app can make two things:

    • it can call the Authorization Server directly and exchange the authorization code for an access token. This will mean that you're dealing with a public OAuth client (no secret is used) and you should implement PKCE for better protection of your app. This also means that your frontend will have to handle the tokens itself - e.g. if you want to keep the token during page refresh you will have to save it in the local storage, etc.

    • it can call your backend and send the authorization code there. Your backend will handle the exchange of code for a token. This means that you can have a confidential OAuth client and use a secret. The backend can save the token in a DB if needed and establish a cookie-based session with your frontend. This means that all calls to the API where the access token is needed will have to go through the backend. The backend can also respond with the access token so that the frontend is able to call APIs directly, but then again you have to take care of handling the token in the front.

    1. Redirect to backend.

    In this scenario, https://myapp.example.com/callback is handled by the backend. You exchange the authorization code for an access token. Again the client can have a secret. You can then save the token in a DB and establish a cookie-based session. The frontend can now call the APIs through the backend and the backend will be able to attach the access token to the API calls. Another solution is to have the backend respond with a redirect to the frontend app and send the access token in the redirect URL. Then the frontend app will be able to use that token (so this would work a bit like the implicit flow for the frontend app). You have to be careful there to meet some security best practices, e.g. send the token in the fragment part of the redirect URI, not as a parameter.

    As you can see, this may be dealt with in many ways. My recommendation is to choose any option where only the backend gets the tokens and saves them and the frontend uses a cookie-based session. This keeps the tokens out of the browser and is currently considered best security practice. (You can read more about the current state of SPA security in a whitepaper we've published at Curity: https://curity.io/resources/documents/single-page-application-security-whitepaper)