Search code examples
authenticationjwtaccess-token

In token-based authentication, who should create the JWT, the app developer or the auth server?


I have a general question on token-based authentication. I've seen multiple guides that seem to say conflicting things, so I'm confused:

Question

Who should be responsible for creating the JWT, the app developer (via the app's backend server) or the auth server (ex. the Identity Provider)?

(1) Here [0], it explains that the developer needs to generate + hash the JWT and use that as the bearer token for any request. From there, the auth server can use the shared secret key to validate the token.

(2) Here [1], it says the auth server generates the JWT and returns it to the client once the login is provided + validated (no backend server involved on the developer's side).

Which one is correct? If they're both correct, how do I know which one to use?

My understanding:

(1) #1 above is one where the developer stores the secret in the backend server of their app. The backen serves as the middle man between the client and the auth server to make authenticated requests without exposing the secret + access token.

(2) #2 above is one where the app has no backend server at all (SPAs like Angular/React). The client interacts with the auth server directly (aka no secrets involved). Per [1], the IdP only uses the client ID, scope and few other things to generate a JWT.

[0] https://enable.cx.sap.com/media/1_uup99qpg (skip to 1:49)

[1] https://auth0.com/blog/handling-authentication-in-react-with-context-and-hooks/ (scroll down to the first block of code under "Add authentication to your app", where the Auth0 instance is configured)


Solution

  • Depending on the project requirements/budget/timeline, the JWT can be created by the developer, or it can be managed by a third party (e.g. Auth0).


    Terms

    Authentication Server

    • Receives user credentials (e.g. username & password)
    • Validates user credentials (e.g. compare username's stored hashed password in the database to the result of hashing the password from the request)
    • If token is valid, server responds with a token that is used to authenticate future requests (often automatically stored in a cookie in the client by passing it in the proper header in the auth server's response, which can then be automatically included with every request).
    • Can be written from scratch (allowing for more customization), or can be handled by tools such as Auth0

    Scenario 1 (SAP)

    This scenario involves making authenticated requests to a third party API.

    • Your frontend accepts user credentials
    • Your backend ("authentication server") validates credentials
    • Your backend responds with a JWT token, created using the RSA Key from SAP, your User ID from SAP, and likely the User ID from your backend server so that you can ensure that the user making a request to authorized to access the data requested. NOTE: Auth0 can be used to create the token, if it supports storing and passing custom values to the JWT
    • Your frontend makes a request to your backend, including the JWT
    • Your backend ensures authorization (Auth0 can be used if it supports creating custom logic for checking authorization), then makes the relevant request (based on the request from the frontend) to the SAP server and passes both the JWT and the API Key (stored on your server) with the request
    • SAP verifies the JWT, and responds to your backend with the requested data
    • Your backend then passes the relevant data to your frontend

    Scenario 2 (Auth0) - YouTube Demo

    This scenario uses a third party auth server to authenticate/authorize routes on both your frontend and backend (both of which will leverage Auth0 tooling).

    • Your frontend directs the user to Auth0's login page
    • Auth0 redirects back to your frontend, where it stores the JWT
    • When a user clicks on a button on your frontend that takes them to a different route (e.g. /profile), your frontend can use Auth0 to see if they are authenticated/authorized and extract relevant user data.
    • When a user clicks on a button on your frontend that makes an API request to your backend, it sends the JWT token with the request, which your backend uses for authenticates using Auth0, and then responds with the relevant data (if the user is authorized to receive it).