Reputation: 1258
Here's the flow:
AuthContext
sets/persists a cookie of accessToken among user profile infoNext docs say I can set outgoing, client-side cookies for the request (emphasis mine):
The cookies function allows you to read the HTTP incoming request cookies from a Server Component or write outgoing request cookies in a Server Action or Route Handler.
My Next.js app has the following structure:
<AuthContext>
<Layout>
<Page>
...
</Page>
</Layout>
</AuthContext>
Current code:
// AuthProvider
"use client";
import { AuthContextType, AuthenticatedUser } from "@/app/@types/auth";
import { ReactNode, createContext, useState } from "react";
import { cookies } from "next/headers";
const AuthContext = createContext<AuthContextType | null>(null);
interface Props {
children?: ReactNode;
}
function AuthProvider({ children }: Props) {
const cookieJar = cookies();
function login(user, persist: boolean) {
const userJson = JSON.stringify({
uid: user.uid,
email: user.email,
emailVerified: user.emailVerified,
displayName: user.displayName,
refreshToken: user.stsTokenManager.refreshToken,
accessToken: user.stsTokenManager.accessToken,
expirationTime: user.stsTokenManager.expirationTime
});
cookieJar.set({
name: "auth",
value: userJson,
httpOnly: true,
expires: persist ? undefined : Infinity
});
}
... // Removed for brevity
}
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
let valid = false;
// check validity
if (!valid)
return NextResponse.redirect(new URL('/auth/login', request.url))
}
export const config = {
matcher: '/dashboard/:path*',
}
Here's my issues and what I can't figure out.
AuthContext
is client-side, whereas middleware.ts
is (currently) a server component (as it's importing next/headers
).
If I attempt to run as-is, I get the following error due to the createContext
of my AuthContext:
You're importing a component that needs next/headers. That only works in a Server Component but one of its parents is marked with "use client", so it's a Client Component.
If I remove use client
from my AuthContext
then I get the following error:
You're importing a component that needs createContext. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
How do I fix this? Specifically, how do I set cookies, then use middleware to read them for authentication purposes? I think I've got all of the pipes in place, but not sure how to hook them up.
Upvotes: 0
Views: 994
Reputation: 21
Cookies are shared between client and server, so you need to just access request.cookies.get('your-cookie') at middleware function.
export async function middleware(request: NextRequest) {
const access_token = request.cookies.get('your-cookie')
if (!!access_token) {
return NextResponse.next()
}
return NextResponse.rewrite(new URL('/', request.url))
}
Upvotes: -1