Skip to content

Commit

Permalink
feat: protected route redirect overwrite per page (#424)
Browse files Browse the repository at this point in the history
Co-authored-by: Zoey <[email protected]>
  • Loading branch information
LouisHaftmann and zoey-kaiser authored Sep 23, 2023
1 parent 55aee8a commit 57c1431
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
3 changes: 2 additions & 1 deletion docs/content/3.application-side/4.protecting-pages.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Protecting Pages

`nuxt-auth` offers different approaches to protect pages:

1. Global protection: Protects all pages with manual exceptions
2. Local protection: Protects specific pages
3. Custom middleware: Create your own middleware
Expand Down Expand Up @@ -48,6 +49,7 @@ That's it! Every page of your application will now need authentication for the u
### Disabling the global middleware locally

To disable the global middleware on a specific page only, you can use the [`definePageMeta` macro](https://nuxt.com/docs/api/utils/define-page-meta#definepagemeta) to turn `auth` off:

```vue
<!-- file: ~/pages/index.vue -->
<template>
Expand All @@ -61,7 +63,6 @@ definePageMeta({ auth: false })

Note: This only works on `pages/`. It notably does not work inside the `app.vue`.


## Local middleware

To protect specific pages with a middleware, you can use the [`definePageMeta` macro](https://nuxt.com/docs/api/utils/define-page-meta#definepagemeta) to turn `auth` on:
Expand Down
14 changes: 14 additions & 0 deletions docs/content/v0.6/3.application-side/4.protecting-pages.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ export default defineNuxtConfig({

That's it! Every page of your application will now need authentication for the user to visit it.

### Middleware Options

#### `unauthenticatedOnly`

Whether to only allow unauthenticated users to access this page. Authenticated users will be redirected to `/` or the route defined in `navigateAuthenticatedTo`

#### `navigateAuthenticatedTo`

Where to redirect authenticated users if `unauthenticatedOnly` is set to true

#### `navigateUnauthenticatedTo`

Where to redirect unauthenticated users if this page is protected

### Disabling the global middleware locally

To disable the global middleware on a specific page only, you can use the [`definePageMeta` macro](https://nuxt.com/docs/api/utils/define-page-meta#definepagemeta) to turn `auth` off:
Expand Down
27 changes: 25 additions & 2 deletions src/runtime/middleware/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,23 @@ import { navigateToAuthPages, determineCallbackUrl } from '../utils/url'
import { useAuth } from '#imports'

type MiddlewareMeta = boolean | {
unauthenticatedOnly: true,
/** Whether to only allow unauthenticated users to access this page.
*
* Authenticated users will be redirected to `/` or the route defined in `navigateAuthenticatedTo`
*
* @default undefined
*/
unauthenticatedOnly?: boolean,
/** Where to redirect authenticated users if `unauthenticatedOnly` is set to true
*
* @default undefined
*/
navigateAuthenticatedTo?: string,
/** Where to redirect unauthenticated users if this page is protected
*
* @default undefined
*/
navigateUnauthenticatedTo?: string
}

declare module '#app/../pages/runtime/composables' {
Expand All @@ -14,7 +29,13 @@ declare module '#app/../pages/runtime/composables' {
}

export default defineNuxtRouteMiddleware((to) => {
const metaAuth = to.meta.auth
const metaAuth = typeof to.meta.auth === 'object'
? {
unauthenticatedOnly: true,
...to.meta.auth
}
: to.meta.auth

if (metaAuth === false) {
return
}
Expand Down Expand Up @@ -60,6 +81,8 @@ export default defineNuxtRouteMiddleware((to) => {
const signInOptions: Parameters<typeof signIn>[1] = { error: 'SessionRequired', callbackUrl: determineCallbackUrl(authConfig, () => to.path) }
// @ts-ignore This is valid for a backend-type of `authjs`, where sign-in accepts a provider as a first argument
return signIn(undefined, signInOptions) as ReturnType<typeof navigateToAuthPages>
} else if (typeof metaAuth === 'object' && metaAuth.navigateUnauthenticatedTo) {
return navigateTo(metaAuth.navigateUnauthenticatedTo)
} else {
return navigateTo(authConfig.provider.pages.login)
}
Expand Down

0 comments on commit 57c1431

Please sign in to comment.