Protecting Routes
~6 minThis guide shows how to restrict access to routes in a Node.js server-side application based on authentication state. You will create reusable middleware that checks whether the current user has an active session before allowing access to protected resources.
Protecting Routes
Prerequisites
- Complete the [Handling Authentication](../handling-authentication) guide to set up the authentication client and session cookie.
How It Works
The `isSignedIn` method checks whether the user's session exists and is still valid. If the access token has expired but a refresh token exists, the SDK automatically refreshes the token before returning the result. Use this method in a middleware function to gate access to protected routes.
Create an Authentication Middleware
export async function requireAuth(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
const sessionId = req.cookies[CookieConfig.SESSION_COOKIE_NAME]
if (!sessionId) {
res.redirect('/sign-in')
return
}
const signedIn = await auth.isSignedIn(sessionId)
if (!signedIn) {
res.redirect('/sign-in')
return
}
next()
}Apply Middleware to Routes
### Protect Individual Routes Apply the middleware to specific routes that require authentication.
app.get('/dashboard', requireAuth, (req, res) => {
res.render('dashboard')
})
app.get('/profile', requireAuth, async (req, res) => {
const sessionId = req.cookies[CookieConfig.SESSION_COOKIE_NAME]
const user = await auth.getUser(sessionId)
res.render('profile', { user })
})Attach User Data to the Request
Extend the request object to carry user information, so protected route handlers can access it without fetching it again.
declare global {
namespace Express {
interface Request {
user?: User
}
}
}
export async function requireAuth(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
const sessionId = req.cookies[CookieConfig.SESSION_COOKIE_NAME]
if (!sessionId) {
res.redirect('/sign-in')
return
}
const signedIn = await auth.isSignedIn(sessionId)
if (!signedIn) {
res.redirect('/sign-in')
return
}
req.user = await auth.getUser(sessionId)
next()
}Handle Token Refresh Failures
The `isSignedIn` method attempts to refresh an expired access token automatically. If the refresh fails (for example, the refresh token has also expired), it returns `false`. The middleware handles this by redirecting to the sign-in route. To distinguish an expired session from a network failure, you can catch errors explicitly:
export async function requireAuth(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
const sessionId = req.cookies[CookieConfig.SESSION_COOKIE_NAME]
if (!sessionId) {
res.redirect('/sign-in')
return
}
try {
const signedIn = await auth.isSignedIn(sessionId)
if (!signedIn) {
res.clearCookie(CookieConfig.SESSION_COOKIE_NAME)
res.redirect('/sign-in')
return
}
} catch (error) {
res.status(500).send('Authentication check failed.')
return
}
next()
}Next Steps
- [Accessing Protected APIs](../accessing-protected-apis): Use the access token to call downstream services