使用 MongoDB 适配器通过 Next.js、Next-auth 和 FastAPI 后端进行安全身份验证和授权

Dib*_*dan 6 next.js fastapi next-auth

我目前正在开发一个项目,该项目使用 Next.js 和 next-auth 作为前端,使用 Python FastAPI 作为后端。我一直使用Google提供程序进行身份验证,并计划将来添加魔术链接登录。我正在利用数据库策略和 MongoDB 适配器来处理用户数据。

虽然我对前端实现有很好的了解,但我很难找出在后端验证用户的最佳方法。

我当前的方法是使用 cookie 中的 next-auth.session-token 并将该令牌发送到后端。在后端,我验证令牌是否合法,确定与令牌关联的用户,并检查令牌是否已过期。为此,我使用 next-auth.session-token 查询由 next-auth 创建的 MongoDB 数据库中的会话集合,并访问用户信息,包括他们的角色。

但是,我担心这种方法的安全性。如果数据库遭到破坏,攻击者可能会获得对所有用户登录令牌的访问权限并滥用它们。这看起来非常不安全,我在下一个身份验证文档中找不到有关此主题的太多信息。

我面临的另一个问题是,由于 next-auth.session-token cookie 只能由后端访问,因此我必须通过代理将所有请求从客户端路由到后端以添加 next-auth.session-请求的令牌。这似乎不是处理这个问题的正确方法。

我想知道是否有更好、更安全的方法来使用 MongoDB 适配器处理 Next.js 前端和 FastAPI 后端之间的身份验证和授权。任何用于增强安全性和改进架构的指导、资源或最佳实践将不胜感激。

我在 [...nextauth].ts 中的设置如下所示:

import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import clientPromise from '../../../utils/mongodb/mongodb';
import { MongoDBAdapter } from '@next-auth/mongodb-adapter';

export default NextAuth({
  // Configure one or more authentication providers
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID as string,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,

      profile(profile) {
        return {
          id: profile.sub,
          name: profile.name,
          googleEmailVerified: profile.email_verified,
          email: profile.email,
          image: profile.picture,
          firstLogin: new Date(),
          role: 'USER',
          locale: profile.locale,
          isSubscribed: false,
        };
      },
    }),
  ],

  session: {
    strategy: 'database',
    maxAge: 7 * 24 * 60 * 60, // 7 days
    updateAge: 30 * 60, // 24 hours
  },

  pages: {
    signIn: '/login',
    signOut: '/',
    error: '/error', // Error code passed in query string as ?error=
    verifyRequest: '/auth/verify-request', // (used for check email message)
    newUser: '/tools/project', 
  },
  callbacks: {
    async session({ session, user }) {
      if (session?.user) {
        session.user.role = user.role;
        session.user.firstLogin = user.firstLogin;
        session.user.locale = user.locale;
        session.user.isSubscribed = user.isSubscribed;
        session.user.googleEmailVerified = user.googleEmailVerified;
        session.user.id = user.id;
      }

      return session;
    },
    async redirect({ url, baseUrl }) {
      return url.startsWith(baseUrl)
        ? Promise.resolve(url)
        : Promise.resolve(baseUrl);
    },
  },

  debug : process.env.NODE_ENV === "development",
  adapter: MongoDBAdapter(clientPromise),
});

Run Code Online (Sandbox Code Playgroud)

如果用户登录,它会在我的 Mongodb 实例中生成三个表:

用户、帐户和会话

桌子