Storing Access Tokens (JWT) in LocalStorage is insecure (XSS vulnerability). Storing them in HttpOnly cookies is safer, but SPAs can’t read cookies. The solution? The **Backend for Frontend (BFF)** pattern.
The Architecture
sequenceDiagram
participant Browser
participant BFF as Reverse Proxy (BFF)
participant IDP as Identify Provider
participant API
Browser->>BFF: Login Request
BFF->>IDP: Redirect to Auth
IDP->>BFF: Return Code + Tokens
BFF->>Browser: Set HttpOnly Cookie (Session)
Browser->>BFF: GET /api/data (Cookie)
BFF->>API: GET /data (Bearer Token)
API-->>BFF: Data
BFF-->>Browser: Data
Using YARP (Yet Another Reverse Proxy)
Microsoft’s YARP is the perfect tool to build a .NET BFF.
// Startup.cs
services.AddReverseProxy()
.LoadFromConfig(Configuration.GetSection("ReverseProxy"))
.AddTransforms(builderContext =>
{
builderContext.AddRequestTransform(async transformContext =>
{
var accessToken = await transformContext.HttpContext.GetTokenAsync("access_token");
transformContext.ProxyRequest.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", accessToken);
});
});
Key Takeaways
- **Zero Tokens in Browser**: The browser only holds an encrypted session cookie.
- **BFF** handles token refresh automatically.
- Significantly reducing the attack surface of your React/Angular app.
Discover more from C4: Container, Code, Cloud & Context
Subscribe to get the latest posts sent to your email.