ChrisPaterson
ChrisPaterson

Reputation: 125

Why is my request for a new access token not returning a new refresh token?

I am using the following code, along with my refresh token, to request a new access token:

exports.getTokenFromRefreshToken = function (user, callback) {
    request.post({
        url:'https://login.microsoftonline.com/12345678-1234-1234-1234-2f189712345/oauth2/token',
        form: {
            grant_type: 'refresh_token',
            refresh_token: refresh_token,
            client_id: client_id,
            client_secret: client_secret,
            resource: 'https://graph.microsoft.com'
        }
    }, function(err, httpResponse, body) {
        if (!err) {
            var tokens = JSON.parse(httpResponse.body);
            console.log('getTokenFromRefreshToken() tokens = ' + JSON.stringify(tokens));
            callback(null, tokens);
        }
    })
};

The httpResponse includes everything that I get when I make the original token request (from the code), but without a new refresh token. I was under the impression that I would also receive a new refresh token. Is that not the case?

Upvotes: 4

Views: 2521

Answers (4)

horacioj
horacioj

Reputation: 737

You get a new refresh token only when you are including the offline_access scope.

ref.: https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-scopes/

The offline_access scope gives your app access to resources on behalf of the user for an extended time. On the work account consent page, this scope appears as the "Access your data anytime" permission. On the personal Microsoft account consent page, it appears as the "Access your info anytime" permission. When a user approves the offline_access scope, your app can receive refresh tokens from the v2.0 token endpoint. Refresh tokens are long-lived. Your app can get new access tokens as older ones expire.

Upvotes: 4

williamthomas
williamthomas

Reputation: 105

I had the exact same issue, caused a headache for a while until the problem was found.

Seems like you are probably logging in with a Guest MS account (previously known as Live) and thus getting a 12hr expiry refresh token with no rolling window.

You need to use a full MS account to get the refresh token back in the response body (which is a token that will last 14 days), with a rolling window of 90 days.

For as long as you use a Guest MSA you will not get a refresh token back. Your code is correctly structured as far as I can see, and I don't believe you need a redirect_uri header as stated above, they are optional fields according to doco.

For more information on the types of refresh tokens, see this blog post:

Azure tokens

Upvotes: 0

Jonathan
Jonathan

Reputation: 126

It looks like it should work except you seem to be missing the redirect URI. I have a working version of this call but it includes this redirect_uri. It produces for me both a new access and refresh token.

--

http://graph.microsoft.io/en-us/docs/authorization/app_authorization

Renew expiring access token using refresh token

The redirect URL that the browser is sent to when authentication is complete. This should match the redirect_uri value used in the first request.

Upvotes: 0

helloden
helloden

Reputation: 96

Refresh tokens aren't refreshed the same way you can get a new access token using the refresh token. When a refresh token expires, you will need to need to get the credentials and do the initial token acquisition again.

More info here: Refreshing an Access Token

Upvotes: 0

Related Questions