auth0 / nextjs-auth0

Next.js SDK for signing in with Auth0
MIT License
2.06k stars 389 forks source link

Session not updating after handleProfile #327

Closed acomito closed 3 years ago

acomito commented 3 years ago

Description

I'm working on a verification email flow. It's known that the session doesn't update automatically every time you call getSession, so it's been suggested you call handleProfile which will then update the session. However, my session is not updating

Reproduction

import { NextApiRequest, NextApiResponse } from 'next'
import auth0 from '../../lib/auth0'

export default async function refreshSession(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {

    await auth0.handleProfile(req, res, {
      refetch: true,
      afterRefetch: async (req, res, session) => {
        return session
      }
    });
    res.end()
  } catch (error) {
    console.log(error)
    res.status(error?.response?.status || 500).json({ message: error.message })
  }
}

If I console.log afterRefetch I can see that the user record has email_verified = true. However, this never updates the session. I tried it with the ProfileOptions and without, still doesn't seem to make a difference.

I feel like I must be missing something somewhere.

Environment

    "@auth0/nextjs-auth0": "1.1.0",
    "next": "10.0.7",
adamjmcgrath commented 3 years ago

Hi @acomito - thanks for raising this

I can't reproduce your issue using handleProfile(req, res, { refetch: true } - When I refetch the user profile, new fields are reflected in the session.

The code you've shared looks fine, can you share some more? How are calling handleProfile then checking the session?

acomito commented 3 years ago

Thanks @adamjmcgrath

Yeah its really strange. Im guessing Im missing a line of code somewhere, or something simple somewhere

We have another api endpint that graphql calls go through. Basically a proxy endpoint that adds the access token to the headers before getting forwarded to our actual gateway

https://gist.github.com/acomito/24a597a59458731d225a4cb33c279b4b

The session there doesn't seem to be getting updated

adarnon commented 3 years ago

I'm running into the same issue. I can add that in my case, the updated_at field of the Session object gets updated, but the rest of the user fields do not. I am trying to force a refetch after an update to app_metadata on the backend (I add the app_metadata to the session object in an Auth0 rule).

After a bit of debugging, it looks like the client.userinfo() call returns an outdated Session object (app_metadata in my case is not updated, if I go to auth0.com management panel the values are different). So I think that, at least in my case, the problem is that the client.userinfo() call merges the old Session object without going through the Auth0 rules pipeline.

adamjmcgrath commented 3 years ago

So I think that, at least in my case, the problem is that the client.userinfo() call merges the old Session object without going through the Auth0 rules pipeline.

Hey @adarnon - rules only run when you authenticate, not when you call the /userinfo endpoint, there's nothing this SDK can do about that I'm afraid.

adamjmcgrath commented 3 years ago

https://gist.github.com/acomito/24a597a59458731d225a4cb33c279b4b

@acomito - thanks for sharing that, the way you're calling getSession looks fine, I'm not able to see any reason in your code why the session would not be updated

acomito commented 3 years ago

Ok. I'm going to keep looking into it and report back.

update: It seems the user object is updated on getSession, but the token is not. When I log getSession, I get the right user info but when I decode the access token it says the email_verified: false

adamjmcgrath commented 3 years ago

Hey @acomito if you want a new access token or id token you'll need to login again (you can do this non interactively using prompt=none) or you can try getting new tokens if you use the refresh grant by doing getAccessToken({ refresh: true }) (assuming you have a refresh token)

acomito commented 3 years ago

Thanks @adamjmcgrath

acomito commented 3 years ago

@adamjmcgrath getAccessToken won't refresh the idToken though will it?

acomito commented 3 years ago

Alright, I did a silent auth but it wasn't through this package (handleLogin doesn't seem to have an option) and so silent auth returns the new ID token but the nextjs-auth0 is unaware and so still has the old one.

Is it possible to update the idToken in the session manually?

Are other people just using the accessToken and hitting the /userinfo endpoint during every single graphql request?

adamjmcgrath commented 3 years ago

Hi @acomito

@adamjmcgrath getAccessToken won't refresh the idToken though will it?

Does it not? (I'm not sure - just wondering if you've tested it)

I did a silent auth but it wasn't through this package (handleLogin doesn't seem to have an option) and so silent auth returns the new ID token but the nextjs-auth0 is unaware and so still has the old one.

You'd need to do Silent Auth through this package in order to update the session, you can do this by using the prompt=none auth param:

await handleLogin(req, res, {
  authorizationParams: {
    prompt: 'none'
  }
});
abineetds commented 2 years ago

Hey @acomito Did you figure out why the refetch wasn't updating the session? I'm trying to do something similar where I'm adding to the user_metadata and then trying to refresh the session, but struggling to get it to update

Fo-Choa commented 2 years ago

I'm running into the same issue. I can add that in my case, the updated_at field of the Session object gets updated, but the rest of the user fields do not. I am trying to force a refetch after an update to app_metadata on the backend (I add the app_metadata to the session object in an Auth0 rule).

After a bit of debugging, it looks like the client.userinfo() call returns an outdated Session object (app_metadata in my case is not updated, if I go to auth0.com management panel the values are different). So I think that, at least in my case, the problem is that the client.userinfo() call merges the old Session object without going through the Auth0 rules pipeline.

Hey @adarnon did you come up with a solution to getting updated app_metadata? Looks like using the management API is the only way...

adarnon commented 2 years ago

We use the management API :(