skip to Main Content
  • I have a NextJS page where I try to implement Next-Auth.
  • I use credentials to login to my Rails API.
  • My API is returning (already) a JWT-Token. (so NextAuth must not create it)

How to implement the Provider.Credentials for [...nextauth].js in that case?

Flow "Diagram"
Next request ---> Next API (with Next-Auth) ---> Rails API (returning Token)

At the momemt I have these options:

 providers: [
    CredentialsProvider({
      name: 'Email',
      credentials: {
        email: { label: "Email", type: "email", placeholder: "[email protected]" },
        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": "[email protected]"}
          return user // MY CONTENT {token: 'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0LCJyb2xl…0.OAGiwjj9O_NsH02lIjA2D4HYZkmTQ3_SqtKcVgaIul0'}

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

A session_token is set in the browser, but that content is something (random?) what I dont have set. Where does this content come from if not from my token?

My Rails API Token Content:

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

Next-Auth API Token Content:

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

Do I have to decode my API token and reassamble that within the Provider.Credentials function?

I implement Next-Auth to provide more Authentications like Twitter and Co, but as well to make use of "useSession" instead of building everything of my own (Wont reinventing the wheel).

2

Answers


  1. So the user that you return from the credentials authorize function will get stored in the JWT (JSON Web Token – which is passed around with all authenticated requests) which is a hashed/encoded (not encrypted by default!) version of the object.

    You can use https://jwt.io to debug and see whats in your JWT. You paste into that site’s debugger field your eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0LCJyb2xl... value and it’ll show you the { iat: 49835898: sub: 47897: email: '[email protected]' }, etc. value.

    jwt.io example

    If your rails API is returning a JWT to you in that fetch call in the authorize function, you can use a library like jwt-decode to decode it right there, and append any values from it which you would like to "persist" in your application to the user object you’re returning from the authorize function in next-auth.

    Login or Signup to reply.
  2. Add Callbacks.

        export default NextAuth({
          providers: [
            CredentialsProvider({
              name: "Email",
              credentials: {
                email: {
                  label: "Email",
                  type: "email",
                  placeholder: "[email protected]",
                },
                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": "[email protected]"}
                  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;
            },
          },
        });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search