diff --git a/src/content/docs/developer-tools/sdks/backend/nextjs-sdk.mdx b/src/content/docs/developer-tools/sdks/backend/nextjs-sdk.mdx index 515bccd7..81bb193a 100644 --- a/src/content/docs/developer-tools/sdks/backend/nextjs-sdk.mdx +++ b/src/content/docs/developer-tools/sdks/backend/nextjs-sdk.mdx @@ -76,6 +76,115 @@ This will handle Kinde Auth endpoints in your Next.js app. **Important!** Our SDK relies on this file existing in this location specified above. +## **Set up middleware** + +Middleware is used to protect routes in your Next.js app, and is a requirement for a seamless authentication experience. + +We provide a `withAuth` helper that will protect routes covered by the matcher. If the user is not authenticated then they are redirected to login and once they have logged in they will be redirected back to the protected page which they should now have access to. + +We require this middleware to run on all routes beside Next.js internals and static files. The provided matcher will do this for you. + +This means that by default, all routes will be protected. You must opt-out public routes - see [opting routes out of middleware protection](#opting-routes-out-of-middleware-protection) for more information. + + + +#### **Middleware configuration** + +Create a `middleware.ts` file in your projects root directory and add the following code: +```ts +import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware"; + +export default function middleware(req) { + return withAuth(req); +} + +export const config = { + matcher: [ + // Run on everything but Next internals and static files + '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', + ] +}; +``` + +#### **Route protection with callback function after authorization** + +You can use the `withAuth` helper as shown below with a `middleware` callback function which has access to the `req.kindeAuth` object that exposes the token and user data. + +```ts +import {withAuth} from "@kinde-oss/kinde-auth-nextjs/middleware"; + +export default withAuth(async function middleware(req) { + console.log("look at me", req.kindeAuth); +}); + +export const config = { + matcher: [ + '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', + ] +}; +``` + +#### **Opting routes out of middleware protection** + +As the middleware matcher is set to protect all routes, you can opt routes out of middleware protection by adding them to the `publicPaths` array. + +```ts +import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware"; + +export default withAuth( + async function middleware(req) { + }, + { + // Middleware still runs on all routes, but doesn't protect the blog route + publicPaths: ["/blog"], + } +); + +export const config = { + matcher: [ + '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', + ], +} +``` + +#### **Additional middleware options** + +There are options that can be passed into the middleware function to configure its functionality. + +- `isReturnToCurrentPage` - redirect the user back to the page they were trying to access +- `loginPage` - define the path of the login page (where the users are redirected to when not authenticated) +- `publicPaths` - define the public paths +- `isAuthorized` - define the criteria for authorization + +```ts +import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware"; + +export default withAuth( + async function middleware(req) { + console.log("look at me", req.kindeAuth); + }, + { + isReturnToCurrentPage: true, + loginPage: "/login", + publicPaths: ["/public", '/more'], + isAuthorized: ({token}) => { + // The user will be considered authorized if they have the permission 'eat:chips' + return token.permissions.includes("eat:chips"); + } + } +); + +export const config = { + matcher: [ + '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', + ], +} +``` + ## **Set up the Kinde Auth Provider** Wrap your app in the Kinde Auth Provider. This will give you access to the Kinde Auth data in your app and will ensure that the tokens are refreshed when needed. @@ -1340,85 +1449,29 @@ if (!(await isAuthenticated())) { } ``` -### Protect routes using middleware - -You can also protect routes with Next.js middleware. - - - -**Default page protection** - -We provide a `withAuth` helper that will protect routes covered by the matcher. If the user is not authenticated then they are redirected to login and once they have logged in they will be redirected back to the protected page which they should now have access to. - -```jsx -import {withAuth} from "@kinde-oss/kinde-auth-nextjs/middleware"; -export default function middleware(req) { - return withAuth(req); -} -export const config = { - matcher: ["/admin"] -}; -``` - -**Page protection with callback function after authorization** - -You can use the `withAuth` helper as shown below with a `middleware` callback function which has access to the `req.kindeAuth` object that exposes the token and user data. - -```typescript -import {withAuth} from "@kinde-oss/kinde-auth-nextjs/middleware"; - -export default withAuth(async function middleware(req) { - console.log("look at me", req.kindeAuth); -}); -export const config = { - matcher: ["/admin"] -}; -``` +## Refreshing Kinde data -**Middleware options** +Our middleware will automatically refresh the tokens in your session in the background. -There are options that can be passed into the middleware function to configure its functionality. +Sometimes, you may want to refresh these tokens yourself. An example of this is when you update Kinde data via the UI or with the Management API. -- `isReturnToCurrentPage` - redirect the user back to the page they were trying to access -- `loginPage` - define the path of the login page (where the users are redirected to when not authenticated) -- `publicPaths` - define the public paths -- `isAuthorized` - define the criteria for authorization +To have these updates immediately reflected in your app, you will need to get the most up-to-date Kinde data and then refresh the tokens in your session. -```typescript -import {withAuth} from "@kinde-oss/kinde-auth-nextjs/middleware"; -export default withAuth( - async function middleware(req) { - console.log("look at me", req.kindeAuth); - }, - { - isReturnToCurrentPage: true, - loginPage: "/login", - publicPaths: ["/public", '/more'], - isAuthorized: ({token}) => { - // The user will be considered authorized if they have the permission 'eat:chips' - return token.permissions.includes("eat:chips"); - } - } -); +To get the most up-to-date Kinde data in your session, use the `refreshTokens` helper function provided by `getKindeServerSession`. -export const config = { - matcher: ["/admin"] -}; -``` + -```jsx -const {refreshTokens} = getKindeServerSession(); +```tsx +'use server' +const { refreshTokens } = getKindeServerSession(); const handleRefresh = async () => { await refreshTokens();