Advice on authentication guards with server middleware
Hi everyone, I was hoping to get some advice on how to handle custom auth within Nuxt. (It's worth noting we're deliberately not using a package, because we have a lot of auth code already that is custom and being re-used for this app)
Right now, I have four pieces set up:
- Various
server
auth endpoints to login, set session cookie, verify session
- Composable useUserSession
that gets the session with a useFetch('/api/session')
- Nuxt middleware that redirects to /login
if not logged in / expired token
- Server middleware that checks if the token is valid (for API routes that will be called from the client)
The problem I have is that the server middleware is hit before any Nuxt middleware, so any request is blocked with a 401 immediately - even the login page. And I know I should not be redirecting in server middleware because then we look at an infinite loop on the middleware.
I added "allowed routes" to the middleware, but then that means I'd have to add every single frontend page to the allowed routes in order for them to then be correctly redirected via nuxt middleware.
I know this can't be the answer - am I missing an obvious development pattern here?
Thanks very much in advance for your advice.3 Replies
Hi @Ollie1700. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
You're facing a common challenge with authentication in Nuxt applications. Based on the knowledge sources, I can provide some guidance on how to structure your authentication flow more effectively.
Understanding the Issue
Your current setup has server middleware checking authentication before Nuxt route middleware runs, which is causing all routes (including public ones like login) to be blocked with 401 errors. This is happening because server middleware executes earlier in the request lifecycle than route middleware.
Recommended Approach
1. Separate API Routes from Page Routes
The key insight is that you should only protect API routes with server middleware, not page routes:
2. Use Route Middleware for Page Protection
For protecting pages, use Nuxt route middleware:
Then apply this middleware to the routes you want to protect:
3. Handle API Authentication Errors
For handling 401 errors from API calls, you can create a custom fetch instance that handles authentication errors:
This approach is recommended in the Custom useFetch in Nuxt documentation.
Important Considerations
1. Return vs. navigateTo: When using middleware, be careful with how you handle navigation. As noted in a Stack Overflow answer, returning
navigateTo()
is the correct approach, not using router.push()
which can cause the "glitchy" behavior you might be experiencing Stack Overflow Post.
2. Avoid infinite redirects: Make sure your middleware doesn't cause infinite redirects by returning nothing when you want to continue the navigation:
This pattern is explained in another Stack Overflow post.
3. Server-side navigation: If you need to handle redirects server-side in specific cases, you can use the approach from this Stack Overflow answer:
By implementing these patterns, you should be able to create a more effective authentication system that properly handles both API routes and page routes without causing infinite redirects or blocking public routes.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@98366949871865856> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Ah of course, I can just distinguish by the
/api
prefix 🤦♂️ I've been so in the weeds of understanding when SSR vs Client happens I didn't consider it!