Using OAuth2/OIDC implicit flow in a front-end framework website is absolutely degenerate. Fite me irl.
You've made the mistake of doubling down on this year's front-end framework for your 5-page website. Now you need to secure the thing; you find the OIDC library with the fewest hundred npm dependencies and get to work. You need to not.
My opinions are summaries and simplifications of items outlined in the OAuth 2.0 Security Best Practice draft. Implicit flow has categorical problems. Primarily, the access token is delivered directly to the client by hash fragment. Presenting the token in such a way exposes the site and token to a multitude of vulnerabilities.
Client-side authorization code flow is a passable alternative with a few caveats. You must use PKCE, as the client cannot secure a secret. And you cannot request refresh tokens as you cannot store them securely. So ultimately you are restricted in your options and have the unfortunate kludge of OAuth2/OIDC libraries bloating your application.
Same-domain is a potential solution, albeit the least feasible. Host the application at the same domain as the API. Use a cookie as an authentication method for both the application and API, and optionally have the API also support bearer tokens. This is not always applicable, as the domain cannot be shared with multiple applications.
However we can use a same-domain strategy by way of an API reverse proxy:
- Shift authentication to the server. Use authorization code flow with PKCE and issue a cookie.
- Host an API reverse proxy within the application's domain. It converts cookie authentication to bearer token API requests.
- Utilize an iframe that keeps your session and access tokens current by way of
The front-end now needs to not care about OAuth2/OIDC at all. Refresh tokens can also be securely stored server-side. The application is largely protected against many vulnerabilities by standard conventions of cookie domain and content security policies.