fix: remove nextjs auth middleware and provide a guide instead (#346)

This commit is contained in:
Bereket Engida
2024-10-26 16:46:08 +03:00
committed by GitHub
parent 8a751b8524
commit d4c4c0b9e9
3 changed files with 39 additions and 103 deletions

View File

@@ -1,17 +1,22 @@
import { authMiddleware } from "better-auth/next-js"; import { client } from "@/lib/auth-client";
import { NextResponse } from "next/server"; import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
export default authMiddleware({ export default async function authMiddleware(request: NextRequest) {
customRedirect: async (session, request) => { const { data: session } = await client.getSession({
const baseURL = request.nextUrl.origin; fetchOptions: {
if (request.nextUrl.pathname === "/dashboard" && !session) { headers: {
return NextResponse.redirect(new URL("/sign-in", baseURL)); //get the cookie from the request
} cookie: request.headers.get("cookie") || "",
return NextResponse.next(); },
}, },
}); });
if (!session) {
return NextResponse.redirect(new URL("/", request.url));
}
return NextResponse.next();
}
export const config = { export const config = {
matcher: ["/dashboard", "/sign-in"], matcher: ["/dashboard"],
}; };

View File

@@ -78,43 +78,33 @@ export async function ServerComponent() {
} }
``` ```
## Middleware ## Middleware
You can use the `authMiddleware` to protect your routes. It's a wrapper around the Next.js middleware. In Next.js, middleware doesnt have access to many Node APIs, so you cant use the usual `auth` instance to validate sessions directly. Instead, you can use `authClient` and pass in the requests cookies to check if a session is valid.
```ts title="middleware.ts"s Heres how it looks:
import { authMiddleware } from "better-auth/next-js"
export default authMiddleware({
redirectTo: "/sign-in" // redirect to this path if the user is not authenticated
})
export const config = {
matcher: ['/dashboard/:path*'],
}
```
you can also pass custom redirect function
```ts ```ts
import { authMiddleware } from "better-auth/next-js"; import { authClient } from "@/lib/auth-client";
import { NextResponse } from "next/server"; import { NextRequest, NextResponse } from "next/server";
export default authMiddleware({ export default async function authMiddleware(request: NextRequest) {
customRedirect: async (session, request) => { const { data: session } = await authClient.getSession({
const baseURL = request.nextUrl.origin; fetchOptions: {
if (request.nextUrl.pathname === "/sign-in" && session) { headers: {
return NextResponse.redirect(new URL("/dashboard", baseURL)); //get the cookie from the request
} cookie: request.headers.get("cookie") || "",
if (request.nextUrl.pathname === "/dashboard" && !session) { },
return NextResponse.redirect(new URL("/sign-in", baseURL)); },
} });
return NextResponse.next();
}, if (!session) {
}); return NextResponse.redirect(new URL("/", request.url));
}
return NextResponse.next();
}
export const config = { export const config = {
matcher: ["/dashboard", "/sign-in"], matcher: ["/dashboard/:path*"],
}; };
``` ```

View File

@@ -1,9 +1,3 @@
import { betterFetch } from "@better-fetch/fetch";
import type { Auth } from "../auth";
import type { Session, User } from "../db/schema";
import { NextRequest, NextResponse } from "next/server";
import { env } from "std-env";
export function toNextJsHandler( export function toNextJsHandler(
auth: auth:
| { | {
@@ -19,56 +13,3 @@ export function toNextJsHandler(
POST: handler, POST: handler,
}; };
} }
/**
* Middleware that checks if the user is authenticated.
* If not, it redirects to the redirectTo URL.
*/
export function authMiddleware(options: {
/**
* The base path of the auth API
* @default "/api/auth"
*/
basePath?: string;
/**
* The URL to redirect to if the user is not authenticated
* @default "/"
*/
redirectTo?: string;
/**
* A custom redirect function
*/
customRedirect?: (
session: {
user: User;
session: Session;
} | null,
request: NextRequest,
) => Promise<any>;
}) {
return async (request: NextRequest) => {
const baseUrl = env.BETTER_AUTH_URL || new URL(request.url).origin;
const basePath = options?.basePath || "/api/auth";
const fullURL = `${baseUrl}${basePath}/get-session`;
const res = await betterFetch<{
session: Session;
user: User;
}>(fullURL, {
headers: {
cookie: request.headers.get("cookie") || "",
},
}).catch((e) => {
return { data: null };
});
const session = res.data || null;
if (options.customRedirect) {
return options.customRedirect(session, request);
}
if (!session) {
return NextResponse.redirect(new URL(options.redirectTo || "/", baseUrl));
}
return NextResponse.next();
};
}