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

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

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

目前我有这些options

 providers: [
    CredentialsProvider({
      name: 'Email',
      credentials: {
        email: { label: "Email", type: "email", placeholder: "meine.email@domain.com" },
        password: {  label: "Passwort", type: "password" }
      },
      async authorize(credentials) {

        // The 'url' is pointing to a Rails API endpoint which returns a JWT Token
        const url = `${process.env.NEXT_PUBLIC_API_URL}/auth/login`;

        const res = await fetch(url, {
          method: 'POST',
          body: JSON.stringify(credentials),
          headers: {
            "Content-Type": "application/json" }
        })
        const user = await res.json()

        // If no error and we have user data, return it
        if (res.ok && user) {
          // I SAW EXAMPLES RETURNING {"email": "blah@tst.com"}
          return user // MY CONTENT {token: 'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0LCJyb2xl…0.OAGiwjj9O_NsH02lIjA2D4HYZkmTQ3_SqtKcVgaIul0'}

        }
        // Return null if user data could not be retrieved
        return null
      }
    })
  ]
}

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

我的 Rails API 令牌内容:

{
  "user_id": 4,
  "roles": [
    "user"
  ],
  "exp": 1631096219
}

Next-Auth API 令牌内容:

{
  "iat": 1631009819,
  "exp": 1633601819
}

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

我实施 Next-Auth 以提供更多的身份验证,如 Twitter 和 Co,但也使用“useSession”而不是构建我自己的所有东西(不会重新发明轮子)。

4

2 回答 2

5

添加回调。

    export default NextAuth({
      providers: [
        CredentialsProvider({
          name: "Email",
          credentials: {
            email: {
              label: "Email",
              type: "email",
              placeholder: "meine.email@domain.com",
            },
            password: { label: "Passwort", type: "password" },
          },
          async authorize(credentials) {
            // The 'url' is pointing to a Rails API endpoint which returns a JWT Token
            const url = `${process.env.NEXT_PUBLIC_API_URL}/auth/login`;
    
            const res = await fetch(url, {
              method: "POST",
              body: JSON.stringify(credentials),
              headers: {
                "Content-Type": "application/json",
              },
            });
            const user = await res.json();
    
            // If no error and we have user data, return it
            if (res.ok && user) {
              // I SAW EXAMPLES RETURNING {"email": "blah@tst.com"}
              return user; // MY CONTENT {token: 'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0LCJyb2xl…0.OAGiwjj9O_NsH02lIjA2D4HYZkmTQ3_SqtKcVgaIul0'}
            }
            // Return null if user data could not be retrieved
            return null;
          },
        }),
      ],
    
      callbacks: {
        async jwt({ token, user, account, isNewUser }) {// This user return by provider {} as you mentioned above MY CONTENT {token:}
          if (user) {
            if (user.token) {
              token = { accessToken: user.token };
            }
          }
          return token;
        },
    
        // That token store in session
        async session({ session, token }) { // this token return above jwt()
          session.accessToken = token.accessToken;
          //if you want to add user details info
          session.user = { name: "name", email: "email" };//this user info get via API call or decode token. Anything you want you can add
          return session;
        },
      },
    });
于 2021-10-11T18:17:49.463 回答
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 authorize,您可以使用jwt-decode之类的库在此处对其进行解码,并从中附加您希望“持久”在应用程序中的任何值到您从authorizenext-auth 中的函数返回的用户对象。

于 2021-09-18T23:49:00.790 回答