我想在下一个身份验证中设置两个自定义 cookie,名为“email”和“accessToekn”。我好像做不到看来 next-auth 正在删除我的 cookie 并设置自己的四个默认值。我该如何设置这两个cookie?这些是我的文件:
这是 authOptions.ts 文件,我尝试在其中设置 cookie:
import axios from 'axios';
import KeycloakProvider from 'next-auth/providers/keycloak';
export const authOptions = {
// Configure one or more authentication providers
cookies: {
email: {
name: 'email',
options: {
httpOnly: true,
sameSite: 'lax',
path: '/',
secure: true,
},
},
accessToken: {
name: 'accessToken',
options: {
httpOnly: true,
sameSite: 'lax',
path: '/',
secure: true,
},
},
},
pages: {
signIn: '/login',
},
secret: process.env.NEXTAUTH_SECRET,
providers: [
KeycloakProvider({
clientId: process.env.KEYCLOAK_ID || '',
clientSecret: process.env.KEYCLOAK_SECRET || '',
issuer: process.env.NEXTAUTH_CLIENT_ISSUER,
//@ts-ignore
profile: (profile) => {
return {
...profile,
id: profile?.sub,
firstName: profile?.given_name,
lastName: profile?.family_name,
mobileNumber: profile?.mobileNumber,
phoneNumber: profile?.phoneNumber,
companyName: profile?.companyName,
companyPhoneNumber: profile?.companyPhoneNumber,
companyAddress: profile?.companyAddress,
};
},
}),
// ...add more providers here
],
callbacks: {
async jwt({ token, account, user }: any) {
// Persist the OAuth access_token to the token right after signin
if (account) {
token.accessToken = account.access_token;
token.refreshToken = account.refresh_token;
token.provider = account.provider;
token.exp = account.expires_at;
token.user = account.user;
token.idToken = account.id_token;
token.user = user;
}
return token;
},
async session({ session, token }: any) {
// Send properties to the client, like an access_token from a provider.
session.accessToken = token.accessToken;
session.refreshToken = token.refreshToken;
session.user = token.user;
// Set custom cookies
if (typeof window === 'undefined') {
const { res } = session;
if (res) {
// Set email cookie
res.setHeader('Set-Cookie', `email=${token.user.email}; Path=/; HttpOnly; Secure`);
// Set accessToken cookie
res.setHeader('Set-Cookie', `accessToken=${token.accessToken}; Path=/; HttpOnly; Secure`);
}
}
return session;
},
},
events: {
signOut: async ({ token }: any) => {
// Kill the session on keycloak server on behalf of user
if (token.provider === 'keycloak') {
await axios.get(
`${process.env.NEXTAUTH_CLIENT_ISSUER}/protocol/openid-connect/logout?id_token_hint=${token.idToken}`,
);
}
},
},
};
这是我的 api/auth/[...nextauth] 文件:
import NextAuth from 'next-auth';
import { authOptions } from './authOptions';
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
这也是我用于该项目的中间件:
import { withAuth } from "next-auth/middleware";
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
"/((?!api|_next/static|_next/image|images|favicon.ico).*)",
],
};
export default withAuth({
// Matches the pages config in `[...nextauth]`
pages: {
signIn: "/login",
},
});
此外,我尝试在您在我的文件树中看到的 axios.ts 文件内使用这些 cookie。但我什至无法获取下一个身份验证默认设置的cookie。它返回未定义。
import axios, { AxiosResponse } from 'axios';
import { getCookie } from '@/utils/cookie';
import errorHandling from '@/services/errorHandling';
export const baseURL = process.env.NEXT_PUBLIC_BACKEND_BASE_URL;
const headers: { [key: string]: any } = {};
const axiosApiInstance = axios.create({
baseURL,
headers,
});
axiosApiInstance.interceptors.request.use((req: any) => {
console.log('cook', getCookie('next-auth.session-token.0'), getCookie('email'));
if (!process.browser && req.headers.common.accessToken) {
req.headers.Authorization = `Bearer ${req.headers.common.accessToken}`;
} else if (getCookie('next-auth.session-token.0')) {
req.headers.Authorization = `Bearer ${getCookie('next-auth.session-token.0')}`;
}
return req;
});
您不需要设置自定义cookie。 设置自定义cookie的目的只是在发出HTTP请求时将自定义数据传递给后端服务。相反,您可以将此自定义数据存储在 NextAuth 会话中,然后在发出 HTTP 请求时从会话中检索它并将其包含在请求标头中。 这种方法更好,因为:
NextAuth 已经可以有效地处理会话管理 您可以避免维护多个 cookie 生命周期 更安全、更集中 它降低了身份验证流程的复杂性 以下是如何实现这一点:
// 1. Store custom data in NextAuth session
导出常量 authOptions = { 回调:{ 异步 jwt({ 令牌, 帐户 }) { 如果(帐户?.access_token){ // 将后端令牌存储在 NextAuth JWT 中 token.accessToken = account.access_token } 返回令牌 }, 异步会话({会话,令牌}){ // 使令牌在会话中可用 session.accessToken = 令牌.accessToken 返回会话 } } }
// 2. 创建自动包含token的HTTP客户端 从 'next-auth/react' 导入 { getSession }
const apiClient = async (url: string, options: RequestInit = {}) => { const 会话 = 等待 getSession()
返回 fetch(url, { ...选项, 标题:{ ...选项.标题, ‘授权’:
Bearer ${session?.accessToken}
,
}
})
}
// 3. 在你的组件/页面中使用它 函数我的组件(){ const { 数据:会话 } = useSession()
const fetchData = async () => { const 响应 = 等待 apiClient('https://api.example.com/data') // 处理响应 } }