juhanakristian / remix-auth-microsoft

Microsoft authentication strategy for remix-auth
MIT License
37 stars 19 forks source link

Question: How to refresh access tokens #16

Open subesokun opened 1 year ago

subesokun commented 1 year ago

Hi, first of all, thanks for this great package :) I wanted to ask if you've any examples available for requesting new access tokens via the refresh token. Any hints would be appreciated. Thanks!

juhanakristian commented 1 year ago

Hi @subesokun this library doesn't take care of refreshing the access token. See related issue on remix-auth-oauth2 https://github.com/sergiodxa/remix-auth-oauth2/issues/37

I'm working on a "kitchen sink" example of using remix-auth-microsoft so I might add an example of this to it. I'll keep this issue open for now, thanks :)

subesokun commented 1 year ago

Awesome, looking forward to it :) Also, I've learned that its not possible to validate the issued Access Token via the standard JWT tooling as it's not a valid JWT... https://tonesandtones.github.io/azure-ad-and-the-unvalidatable-access-token/ If I add a custom scope as mentioned on that blog, then the token can't be used anymore for accessing the MS Graph API :/ Does your "kitchen sink" example also includes some code to validate the token?

harbar20 commented 1 year ago

Bumping to add my support for showing an example of refresh tokens.

For my use-case, I used this example, but it seems that the MicrosoftStrategy doesn't provide a refresh token for me to handle myself. Is this just a missing feature of the Strategy, or is there something else I need to add in order to get access to the refresh token after authentication?

juhanakristian commented 1 year ago

Hi @harbar20 It seems that to get the refresh token you need to add offline_access to the scope.

let microsoftStrategy = new MicrosoftStrategy<User>(
{
    ...
    scope: "openid email profile offline_access",
    ...
  },

I've now updated the example with code that shows one way you can use the refresh token in a loader to get a new access token (see app/routes/profile.tsx).

Note that I also changed the verify callback (in auth.server.ts) to return the access token expiration time needed to check if the token needs to be refreshed.

Hope this helps 🙂

harbar20 commented 1 year ago

My code for refreshing a user is here: https://pastebin.com/dEvxK48B It's based on yours. I just took what you had in profile.tsx and moved it to its own function so I could get the user from any route.

For some reason, the getUser function returns the following when I run the function to refresh:

{
  size: 0
}

What does that mean, and why is it returning that? I know for a fact that the refresh is working, because of the logging statements, but for some reason the json() function is returning that. Could it be because of the Set-Cookie failing? And if so, why would it fail?

harbar20 commented 1 year ago

Never mind, I was just logging at the wrong place. That error came from me trying to make a request to the Microsoft Graph API for Outlook Calendar using the access token. I got a 401 Unauthorized because the OAuth obviously didn't authorize me to be able to request someone's calendar information.

Which brings me to my other problem. How do I get that authorization? From what I understand, the scopes built into the strategy don't allow for adding scopes for Microsoft Graph. What is your suggestion for me to be able to request Outlook Calendar information using Microsoft Graph?

bluefire2121 commented 1 year ago

@juhanakristian in your example, how are you returning the accessToken, refreshToken, expiresAt, email, and name without exceeding the maximum cookie length of 4093 bytes?

TheNoisyMonk commented 3 months ago

Was there ever an update on the question above? @bluefire2121 @juhanakristian