Authentication
To make information about the authenticated user available to your pages and UI components, you usually define pageContext.user
at renderPage()
:
// Vike server middleware
app.get('*', async (req, res) => {
// Authentication middlewares (e.g. Passport.js and Grant) provide information about the
// logged-in user at req.user
const user = req.user
/* Or when using a third-party authentication provider (e.g. Auth0):
const user = await authProviderApi.getUser(req.headers)
*/
const pageContextInit = {
urlOriginal: req.url,
// Make the user object available at pageContext.user
user
}
const result = await renderPage(pageContextInit)
/* ... */
})
You can then access pageContext.user
from any UI component using usePageContext()
.
You can pass any custom
pageContext
property torenderPage()
, see API >pageContext
> Custom.
In principle, you can use Vike with any authentication tool such as:
Login flow
By using guard()
with throw redirect()
or throw render()
you can:
- Implement login flows.
- Protect private pages from unprivileged access.
// /pages/admin/+guard.js
import { render, redirect } from 'vike/abort'
export const guard = (pageContext) => {
const { user } = pageContext
if (user === null) {
// Render the login page while preserving the URL. (This is novel technique
// which we explain down below.)
throw render('/login')
/* The more traditional way, redirect the user:
throw redirect('/login')
*/
}
if (user.role !== 'admin') {
// Render the error page and show message to the user
throw render(403, 'Only admins are allowed to access this page.')
}
}
Using
render('/login')
instead ofredirect('/login')
allows the URL to be preserved during the entire login flow:
- Unauthenticated user goes to URL
/admin
and sees the login page. (URL is/admin
.)- User fills the sign-in form and successfully logs in. (URL is still
/admin
.)- Reload the page, the user now sees the admin page. (URL is still
/admin
.)See example.
You can also define a guard()
hook that applies to multiple pages:
// /pages/+guard.js
// This guard() hook applies to all pages: the file is located at /pages/+guard.js
// and therefore applies to all /pages/**/+Page.js
import { render } from 'vike/abort'
export const guard = (pageContext) => {
if (!pageContext.user) {
throw render('/login')
}
}