Next-Auth with Provider.Credentials:当 API 已经返回 JWT 令牌时如何实现?

Jan*_*Jan 14 rails-authorization jwt next-auth

    \n
  • 我有一个 NextJS 页面,我尝试在其中实现 Next-Auth。
  • \n
  • 我使用凭据登录我的 Rails API。
  • \n
  • 我的 API(已经)返回 JWT 令牌。(所以 NextAuth 不能创建它)
  • \n
\n

在这种情况下如何实现Provider.Credentialsfor呢?[...nextauth].js

\n

流程“图”\nNext request ---> Next API (with Next-Auth) ---> Rails API (returning Token)

\n

目前我有这些options

\n
 providers: [\n    CredentialsProvider({\n      name: \'Email\',\n      credentials: {\n        email: { label: "Email", type: "email", placeholder: "meine.email@domain.com" },\n        password: {  label: "Passwort", type: "password" }\n      },\n      async authorize(credentials) {\n\n        // The \'url\' is pointing to a Rails API endpoint which returns a JWT Token\n        const url = `${process.env.NEXT_PUBLIC_API_URL}/auth/login`;\n\n        const res = await fetch(url, {\n          method: \'POST\',\n          body: JSON.stringify(credentials),\n          headers: {\n            "Content-Type": "application/json" }\n        })\n        const user = await res.json()\n\n        // If no error and we have user data, return it\n        if (res.ok && user) {\n          // I SAW EXAMPLES RETURNING {"email": "blah@tst.com"}\n          return user // MY CONTENT {token: \'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0LCJyb2xl\xe2\x80\xa60.OAGiwjj9O_NsH02lIjA2D4HYZkmTQ3_SqtKcVgaIul0\'}\n\n        }\n        // Return null if user data could not be retrieved\n        return null\n      }\n    })\n  ]\n}\n
Run Code Online (Sandbox Code Playgroud)\n

session_token 在浏览器中设置,但该内容是我没有设置的内容(随机?)。如果这些内容不是来自我的令牌,那么它来自哪里?

\n

我的 Rails API 令牌内容:

\n
{\n  "user_id": 4,\n  "roles": [\n    "user"\n  ],\n  "exp": 1631096219\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Next-Auth API 令牌内容:

\n
{\n  "iat": 1631009819,\n  "exp": 1633601819\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我是否必须解码我的 API 令牌并在 Provider.Credentials 函数中重新组装它?

\n

我实现 Next-Auth 来提供更多像 Twitter 和 Co 这样的身份验证,但也利用“useSession”而不是构建我自己的所有内容(不会重新发明轮子)。

\n

小智 11

添加回调。

\n
    export default NextAuth({\n      providers: [\n        CredentialsProvider({\n          name: "Email",\n          credentials: {\n            email: {\n              label: "Email",\n              type: "email",\n              placeholder: "meine.email@domain.com",\n            },\n            password: { label: "Passwort", type: "password" },\n          },\n          async authorize(credentials) {\n            // The \'url\' is pointing to a Rails API endpoint which returns a JWT Token\n            const url = `${process.env.NEXT_PUBLIC_API_URL}/auth/login`;\n    \n            const res = await fetch(url, {\n              method: "POST",\n              body: JSON.stringify(credentials),\n              headers: {\n                "Content-Type": "application/json",\n              },\n            });\n            const user = await res.json();\n    \n            // If no error and we have user data, return it\n            if (res.ok && user) {\n              // I SAW EXAMPLES RETURNING {"email": "blah@tst.com"}\n              return user; // MY CONTENT {token: \'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0LCJyb2xl\xe2\x80\xa60.OAGiwjj9O_NsH02lIjA2D4HYZkmTQ3_SqtKcVgaIul0\'}\n            }\n            // Return null if user data could not be retrieved\n            return null;\n          },\n        }),\n      ],\n    \n      callbacks: {\n        async jwt({ token, user, account, isNewUser }) {// This user return by provider {} as you mentioned above MY CONTENT {token:}\n          if (user) {\n            if (user.token) {\n              token = { accessToken: user.token };\n            }\n          }\n          return token;\n        },\n    \n        // That token store in session\n        async session({ session, token }) { // this token return above jwt()\n          session.accessToken = token.accessToken;\n          //if you want to add user details info\n          session.user = { name: "name", email: "email" };//this user info get via API call or decode token. Anything you want you can add\n          return session;\n        },\n      },\n    });\n
Run Code Online (Sandbox Code Playgroud)\n

  • 通过额外的支持信息可以改进您的答案。请[编辑]添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以[在帮助中心](/help/how-to-answer)找到有关如何写出好的答案的更多信息。 (5认同)

ndo*_*m91 0

因此,您从凭证函数返回的用户authorize将存储在 JWT(JSON Web 令牌 - 与所有经过身份验证的请求一起传递)中,这是对象的散列/编码(默认情况下不加密!)版本。

您可以使用https://jwt.io进行调试并查看 JWT 中的内容。您将您的值粘贴到该站点的调试器字段中eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0LCJyb2xl...,它会向您显示{ iat: 49835898: sub: 47897: email: 'abc@xyz.com' }等值。

jwt.io 示例

如果您的 Rails API 在函数的 fetch 调用中返回 JWT ,您可以使用jwt-decodeauthorize之类的库对其进行解码,并附加您想要在应用程序中“保留”的任何值到您从 next-auth 中的函数返回的用户对象。authorize