next.js 下一个认证谷歌登录获取自定义令牌

vxf3dgd4  于 2023-08-04  发布在  其他
关注(0)|答案(1)|浏览(83)

我使用的是next js、next auth和一个自定义后端(flask),在这里我使用的是用jwt令牌保护的API端点。在下一个js前端中,我希望使用useSession挂钩访问这个jwt标记,以便向这个API端点发出请求。有了CredentialsProvider,一切都能正常工作。我能够注册和登录一个用户,并可以获得访问jwt令牌。当我使用useSession和凭据登录时,我有以下格式的数据,这是我想要的(token.sub是我的jwt访问令牌):

{
    "data": {
        "session": {
            "user": {},
            "expires": "2023-02-06T21:35:50.296Z"
        },
        "token": {
            "sub": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY3MzEyNzM1MCwianRpIjoiZDJmODIwZjAtOGYxOS00Y2Q5LTk0Yxxxxxxx",
            "iat": 1673127350,
            "exp": 1675719350,
            "jti": "53b9fcaa-3aa9-4567-9381-341231144e72"
        }
    },
    "status": "authenticated"
}

字符串
然而,当我使用谷歌登录时,我得到的格式是:所有我想要的是从我的后端获得jwt访问令牌。

{
    "data": {
        "session": {
            "user": {
                "name": "google name",
                "email": "google email",
                "image": "google pic"
            },
            "expires": "2023-02-06T21:24:09.905Z"
        },
        "token": {
            "name": "google user name",
            "email": "google email",
            "picture": "google pic",
            "sub": "115092xxxxxxx",
            "iat": 16731xxxx,
            "exp": 1675xxxx6,
            "jti": "1fc246fa-xxxxxx"
        }
    },
    "status": "authenticated"
}


这是下一个身份验证的代码。为了获得google登录的访问权限,我添加了登录回调,并在那里添加了请求到我的后端,以获得jwt访问令牌。

import NextAuth, { NextAuthOptions } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import GoogleProvider from "next-auth/providers/google"
import API from "../../../API";
import axiosHandler from "../../../axios-handler";

const authOptions = {
  session: {
    strategy: "jwt",
  },
  providers: [
    CredentialsProvider({
      type: "credentials",
      credentials: {},
      authorize: async (credentials, req) => {
        const loginResponse = await axiosHandler.post(credentials.isRegister? API.REGISTER :API.LOGIN, credentials)
        if(loginResponse.data){
          return {
            id: loginResponse.data.token,
            token: loginResponse.data.token,            
          }
        }
        return null
      },
    }),
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    })
  
  ],
  pages: {
    signIn: "/auth/signin",
  },
  callbacks: {
    async session({ session, user, token }) {
      return {session, user, token}
    },

    async jwt({ token, user, account, profile, isNewUser }) {
      return token
    },
    async signIn({user, account}){
      if(account?.provider ==="google"){
        const googleAuthData = {
          name: user.name,
          email: user.email,
          image: user.image,
          authProvider: 'google',
          password: ''
      }
      const loginResponse = await axiosHandler.post(API.LOGIN, 
        {
          name: googleAuthData.name, 
          email: googleAuthData.email, 
          secretKey:"xxx"})
      if(loginResponse.data){
        return {
          ...user,
          id: loginResponse.data.token,
          token: loginResponse.data.token
        }
      }
      }
      return user
      
    }
  },
};

export default NextAuth(authOptions);

50few1ms

50few1ms1#

我遇到了一个非常类似的挑战,在我的情况下,后端需要userId来验证来自nextAuth的accessToken。但是那是不可能的。我的流程与你的略有不同,因为我依赖于下一个auth来生成jwt,而我确保后端使用相同的TOKEN_SECRET和后端用于生成jwt的算法。

NB:* 我在前端和后端都使用了相同的JWT算法和Secret *

我认为对于您的用例,您可能需要自定义jwt.encode函数,向后端发出API请求,然后返回后端提供的访问令牌

jwt: {
 ...,
 encode: async (data: any) => {
   const { secret, token } = data;
   const { email, picture, name } = token;

   // make an API call
   // set the encodedToken with accessToken from BE

   return encodedToken;
 }
}

字符串

相关问题