我正在尝试编写一个 API 路由,我想在其中检查用户是否经过身份验证以及它是否是管理员。为此,我尝试调用 getServerSession 方法,它确实返回一个会话,但我的自定义字段设置为“未定义”,还要注意,如果我在 getServerSideProps(ctx) 中使用相同的方法,它会按预期工作,所以这只发生在API 路由。
getServerSideProps 中的会话对象:返回预期的
[..nextauth].ts
import type { NextAuthOptions, Session } from 'next-auth';
import NextAuth from 'next-auth';
import type { JWT } from 'next-auth/jwt';
import CredentialsProvider from 'next-auth/providers/credentials';
import { verifyPassword } from '@/lib/auth';
import { connectToDatabase, initUserTable } from '@/lib/db';
import User from '@/lib/dbmodels/user';
export const authOptions: NextAuthOptions = {
secret: process.env.NEXTAUTH_SECRET,
session: {
strategy: 'jwt',
},
providers: [
CredentialsProvider({
name: 'Credentials',
credentials: {
email: { label: 'Email', type: 'text' },
password: { label: 'Password', type: 'password' },
},
async authorize(credentials) {
if (!credentials?.email || !credentials?.password) {
throw new Error('Email-ul sau parola sunt greșite');
}
const db = await connectToDatabase();
await initUserTable(db);
const user = await User.findOne({
where: { email: credentials?.email },
});
if (!user) {
db.close();
throw new Error('Acest utilizator nu există');
}
const isValid = await verifyPassword(
credentials?.password,
user.password
);
if (!isValid) {
db.close();
throw new Error('Email-ul sau parola sunt greșite');
}
db.close();
return user.dataValues;
},
}),
],
callbacks: {
async jwt({ user, token }) {
const newToken = { ...token };
if (user?.role) {
newToken.role = user.role;
}
if (user?.id) {
newToken.id = user.id;
}
return newToken;
},
async session({ session, token }: { session: Session; token: JWT }) {
const newSession = { ...session };
newSession.user.role = token.role as 'user' | 'admin';
newSession.user.id = token.id as string;
delete newSession.user.image;
return newSession;
},
},
};
export default NextAuth(authOptions);
API 路线
async function handler(req: RegisterNextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not supported' });
}
const { name, email, password, role = 'user' } = req.body;
const emptyData = name == null || email == null || password == null;
const session = await getServerSession(req, res, authOptions);
const user = session?.user;
if (!user || !user?.email) {
return res.status(401).json({ error: 'You must be logged in.' });
}
if (user?.role !== 'admin') {
return res.status(401).json({ error: 'Only admins can create users!' });
}
// Rest of the code
}
类型文件
import type { DefaultSession } from 'next-auth';
declare module 'next-auth' {
interface Session {
user: User & DefaultSession['user'];
}
interface User {
id: string;
name: string;
email: string;
role?: 'user' | 'admin';
}
}
我也希望能够在 API 路由中访问角色对象,但似乎只能在 getServerSideProps() 下一个函数中访问。
别忘了扩展
SessionBase
interface Session extends SessionBase {
user?: User
}