Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update documentation for version 2.5.0 of the Next.js SDK #305

Merged
merged 6 commits into from
Feb 7, 2025
Merged
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 120 additions & 69 deletions src/content/docs/developer-tools/sdks/backend/nextjs-sdk.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Comment on lines +109 to +110
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Strengthen the requirement statement

The current wording doesn't fully emphasize that middleware is now a requirement in version 2.5.0. Consider revising to make this clearer.

-Middleware is used to protect routes in your Next.js app, and is a requirement for a seamless authentication experience.
+Middleware is a required component in version 2.5.0+ for handling authentication and token refreshes in your Next.js app. It is no longer optional.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Middleware is used to protect routes in your Next.js app, and is a requirement for a seamless authentication experience.
Middleware is a required component in version 2.5.0+ for handling authentication and token refreshes in your Next.js app. It is no longer optional.

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.

<Aside>

Want to learn more about middleware? Check out the [Next.js middleware docs](https://nextjs.org/docs/app/building-your-application/routing/middleware).

</Aside>

#### **Middleware configuration**

Create a `middleware.ts` file in your project's 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.
Expand Down Expand Up @@ -1340,87 +1449,29 @@ if (!(await isAuthenticated())) {
}
```

### Protect routes using middleware

You can also protect routes with Next.js middleware.

<Aside>

As of right now the middleware in the app router does not work when trying to redirect to `api/auth/login`. This is because of Next.js caching which causes issues during authentication.

</Aside>

**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"]
};
```

**Middleware options**
## Refreshing Kinde data

There are options that can be passed into the middleware function to configure its functionality.
Our middleware will automatically refresh the tokens in your session in the background.

- `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
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.

```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 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.

export const config = {
matcher: ["/admin"]
};
```
To get the most up-to-date Kinde data in your session, use the `refreshTokens` helper function provided by `getKindeServerSession`.

## Refreshing Kinde data
<Aside title="Important">

Kinde data can be updated via the UI or with the Management API. To have these updates be reflected in your app, you will need to get the most up-to-date Kinde data and then refresh the tokens in your session.
Due to limitations in Next.js, this will only work in a route handler or server action.

To get the most up-to-date Kinde data in your session, use the `refreshTokens` helper function.
</Aside>

```jsx
const {refreshTokens} = getKindeServerSession();
```tsx
'use server'

const handleRefresh = async () => {
const { refreshTokens } = getKindeServerSession();
await refreshTokens();
}

Expand Down