“Everything you always wanted to know (but were afraid to ask)”
Thanks to Vittorio Bertocci for this excellent blog post. Like (perhaps) many others, I noticed the 2018 change in the OAuth2 Working Group’s recommendation regarding the use of the Implicit flow for web SPAs, and it concerned me greatly at the time. Like (very probably) many others however, I had a hard time conceptualizing how to adopt ‘Authorization Code Grant w\PKCE’ within a SPA. It’s semi-easy to imaging how it might be done, but very hard to implement without the use of refresh tokens. Also, the working group recommendation provides no helpful ‘next steps’ (or pointers to any).
This article provides a very nice wrapper around the subject of ‘should I switch from Implicit Flow to ACG+PKCE?’, and also provides some concrete steps regarding how one can make that decision, and actually begin to make the switch.
Many thanks to Auth0 and to Mr. Bertocci.
Thank you Joe for your kind words! I am so very glad you found the post useful.
Thank you for the detailed and actionable summary around the state of OAuth2 implicit grant and SPAs. I especially appreciate the treatment of renewing access tokens and different SPA topologies, as this helps connect the specification with real-world implementation choices. I am not a full-time identity and authorization expert, so seeing mention of future solutions like token binding and mutual TLS authentication helps me know where this area is heading.
Kudos to you and Auth0 in general - your blog posts consistently communicate difficult technical subjects with clarity and pragmatism. You help educate the community on general solutions with or without use of Auth0, which I appreciate. Fantastic job!
Hey Shane, thank you for the kind words! I am very glad this was helpful to you. Thank you for taking the time to highlight the parts you found most useful, this will help us to double down on similar areas/aspects in future posts.
@Vittorio Great article!
Very useful information for keeping on top of Best Practices in easy-to-consume bite sized chunks which any developer without Identity and Security expertise can understand.
I won’t get my hopes up but on the off chance you’re able to disclose this information, when can we expect support for ACG+PKCE to land in Auth0.js?
Hey Charles, thanks for the nice feedback!
Sharing dates is always tricky, as one can never be sure whether high pri items show up to disrupt timelines. I can only double down on our intent to make this capability available in SDK form as soon as it’s feasible. Thanks!
Thanks @Vittorio for providing complete information on best practices one can use if they have to upgrade their implicit grant flows in SPA.
Thank you Baskarrao for the kind words, I am glad you found the article useful!
This has been a really helpful post, that one of your colleagues put me on to.
I have one quick question if that is OK? With your alternative solutions where you control the backend, could you not extend option 1 such to support third party apis by the backend acting as reverse proxy.
You could have routing in your spa backend such that myapp.com/api would obtain access token and then forward the request onto thirdpartyapi.com/someendpoint with the access_token and then simply return whatever the response is to the spa. Access to myapp.com/api via session cookie and no tokens delivered to the client ? In theory this gets around the short comings of the second approach in that the application requesting the token is the same as forwards the api request and dont need to be an authorization server.
Interested in your thoughts on the above anyway.
In order to proceed with OAuth2 Authorization Code grant type, the SPA needs to store and send the client’s password, according to 4.1.3 of The OAuth 2.0 Authorization Framework.
The requirement to store the password was one of the reasons to avoid this grant type in SPA’s. But now this grant type is recommended.
Question: how can SPA get and store the client password in a secure manner?
Hi @Andrey, welcome to the Auth0 Community!
If I may chime in here, we are indeed saying that the Authorization Code + Proof Key for Code Exchange (PKCE) grant type is now recommended for SPAs. As described in the article, “code challenge” and “code challenge method” values are sent to the
/authorize endpoint, and then a verifier is sent when calling the
/token endpoint. This allows the authorization server to safely verify that the token is being sent back to the client that requested it.
If you have a look at the API docs for Authorization Code Flow + PKCE, there is no requirement to send the client secret when requesting the access token. Therefore, there is no requirement for you to store one, securely or otherwise.
Hope that makes sense!
Thanks so much for this thoughtful resource! Most of the logic here (very reasonably) relies on redirect or origin domain validation. Any thoughts on approaches for when the client code is running in an untrusted domain? The use case I’m thinking of is e.g. googleusercontent.com, running as a GSuite Add-On. But I think there are other similar use cases.
A year ago, I was surprised to run into Safari ITP. It thwarted my plan to use cookie-based authentication across domains. I appreciate your deep dive into alternatives and the associated mitigations needed to secure them. Thank you for this excellent blog post!
We fight to get everyone covered!
Great post showing the difference between the new PKCE and the old Implicit grant flow!
So for Universal Login, I should go for new auth-spa-js that provides the PKCE for free.
But, if I want to go for Embedded Login, should I use the old auth0.js or is there a way to use the new SDK with PKCE for embedded login? (Supposing would be like getTokenSilently passing the credentials)
@caio.bos Support for Embedded Login with PKCE is on our roadmap, but unfortunately we don’t have an ETA for you just yet.
A post was split to a new topic: Auth0.jS Embedded Login and MFA
How can I change response_mode to ‘fragment’ (default is ‘web_message’) in @auth0/auth0-spa-js? Thanks
auth0-spa-js doesn’t support the changing of the response mode or response type (amongst other things), as it has been designed to support a very specific authentication flow. A side effect of this is it allows us to keep the development API simple.
If you need that kind of flexibility, check out the auth0.js SDK, which allows you to completely customize the authentication flow at the expense of simplicity.