DEV Community

Tomasz
Tomasz

Posted on

What is the most convenient and secure way to authenticate single page applications?

I've been recently learning different ways to secure SPA's with Oauth 2.0. There are plenty of advices over the web, but they continually contradict one another.

Let me share my findings:

The first approach which took my attention was the Oauth 2.0 extension called PKCSE. In the first glance it looks great (no server needed), but when going deeper it has some disadvantages. Two which concerned me the most are:

where to securely store the access_token
where to store securely long lived refresh_token (local storage, in memory etc. is not a case because of XSS)

The second one I saw is to use a back-end for front-end server under the same domain (same nginx with routing all /api/* calls into my backend server). In this case the OAuth client will be the back-end server which can just implement the authorization flow and forward all request to dedicated resource api service. At the end of authorization flow it it will redirect browser to the SPA home page with the following COOKIE:

ACCESS_TOKEN=API_ACCESS_TOKEN
secure: true
httpOnly: true
SameSite: secure
expire: API_ACCESS_TOKEN_EXPIRE
The cookie from the above will be included into the all AJAX requests from the SPA to my back-end api (via nginx - same domain). Also it will mitigate the risk of XSS and CSRF attacks.

The third approach (similar to the 2nd one) but to store access_token on the server side and authenticate SPA with the generated SESSION_ID. It introduces a state in the back-end server - it is something i would like to avoid.

The fourth one (still similar to the 2nd one) but back-end server will generate JWT token with access_token inside the payload and will return it in the secure, SameSite, httpOnly cookie. In this approach back-end server can validate the token first before the request is forwarded to the resource server with the access_token. In terms of disadvantages the back-end server have to keep security keys to validate/generate token (maybe it is over engineering and just forwarding access_token to the resource API will be good enough)

Personally I feel like the second approach is kind of a good balance between security and simplicity ? Do you have any better ideas of securing SPA ? Please share your thoughts and correct me if I'm wrong in my small investigations.

Links:

https://www.pingidentity.com/en/company/blog/posts/2021/refresh-token-rotation-spa.html
https://stackoverflow.com/questions/20963273/spa-best-practices-for-authentication-and-session-management
https://curity.io/resources/learn/spa-best-practices/

Top comments (0)