SPA and tokens storage

The documentation about token storage mentions the following:

  • If the SPA backend can handle the API calls, then it functions similar to a tradition web application that handle tokens server-side using:
  • If the SPA backend cannot handle the API calls, then it functions similar to a mobile application that stores tokens in the SPA backend, but the SPA needs to fetch the tokens from the backend to perform requests to the API. A protocol needs to be established between the backend and the SPA to allow the secure transfer of the token from the backend to the SPA.
  • If you have a SPA with no corresponding backend server, your SPA should request new tokens on login and store them in memory without any persistence. To make API calls, your SPA would then use the in-memory copy of the token.

The second bullet point has been questioned multiple times in the forums but no answer really gets to the bottom of it and it really puzzles me:

I do not understand why the SPA could not use the Authorization Code Flow even if the SPA backend cannot handle API calls. And if this flow can be used, then what would be the need of storing tokens on the server side and fetching them from the backend instead of the authorization server.
Mainly, I do not understand how having a SPA backend that can handle API calls is different to the SPA making the API calls in term of getting tokens and storing them.

@dan.woda , in this related topic, you reply to this question with:

This would look like a more traditional web app in terms of how the token is stored. The SPA will keep a session with the server using cookies, but the token will be held server side, making it more secure in that sense.

How is that more secure than relying on the Authorization Code Flow and storing tokens in memory?

Thanks

Hi @hdepalma,

Welcome to the Auth0 Community!

A SPA is a public client, which means they cannot securely store credentials, like the client secret.

In the OAuth 2.0 Specification, it states:
image
(Reference: RFC 6749 - The OAuth 2.0 Authorization Framework)

Hence why, a SPA needs to use the Authorization Code flow with PKCE. See here for an explanation.

Ultimately, PKCE is more secure because a malicious person cannot just take the authorization code to exchange it for an access token. They must also provide the code verifier, thus making this flow more secure.

Let me know if you have any follow-up questions.

Cheers,
Rueben

Thanks @rueben.tiow,

It totally aligns with my thoughts, however it does not clarify what the second bullet point quoted below means in this context:

  • If the SPA backend cannot handle the API calls, then it functions similar to a mobile application that stores tokens in the SPA backend, but the SPA needs to fetch the tokens from the backend to perform requests to the API. A protocol needs to be established between the backend and the SPA to allow the secure transfer of the token from the backend to the SPA.

What is the need for storing tokens on the SPA backend when using Authorization Code Flow? Tokens are provided by the Authorization server and refreshed when needed, I do not see the need of storing them on the backend.

Hi @hdepalma,

Thanks for the reply.

Firstly, when SPAs use the Authorization Code flow with PKCE, this method allows the SPA to obtain and manage the token directly and renew it. Tokens are usually stored in memory, which presents a security risk as they are susceptible to potential theft when stored in the browser. Therefore, tokens require careful handling.

On the contrary, when a SPA delegates API calls to a backend, the backend then manages both the tokens and the API calls. This method involves storing the tokens on the backend, which is inherently more secure as it prevents the tokens from being exposed to the SPA’s front end.

Thanks,
Rueben

Thanks again @rueben.tiow ,

Your scenario suggests that the SPA backend makes the calls to the API. In that case, the SPA uses the Authorization Code Flow to get an authorization to its backend and then the backend can use the Client Credential Flow to interact with the API (or directly transfer the SPA token, or exchange the token, …). This perfectly makes sense to me.

However, the documentation mentions this:

If the SPA backend cannot handle the API calls, then it functions similar to a mobile application that stores tokens in the SPA backend, but the SPA needs to fetch the tokens from the backend to perform requests to the API

Which clearly states that the SPA is making the calls to the API, not the backend. Then if the SPA makes the calls to the API, why would it need to fetch the token from the backend first?
Can someone please detail the sequences for the SPA to make an API call?

Here is my personal interpretation of the documentation, which does not make much sense:

  1. SPA gets a token using Auth Code Flow
  2. SPA fetch a token from its backend (using the token received above)
    1. SPA backend gets a token using Client Cred Flow
    2. SPA backend sends back this token to SPA
  3. SPA makes an API call using the token fetched from the backend

But obviously, for performance reasons, this cannot be done on each call! So the SPA would have to cache the backend token somewhere and it is then not more secure… Which comes back to why not directly using the token retrieved via Auth Code Flow…

As mentioned previously, this statement in the documentation is really confusing for many people and it either needs to be clarified or amended if not practical.

Thanks