'Not getting a refresh token https://login.microsoftonline.com/common/oauth2/v2.0/token

Response =

{
'token_type': 'Bearer', 
'scope': 'profile openid email https://graph.microsoft.com/Directory.Read.All https://graph.microsoft.com/Presence.Read https://graph.microsoft.com/Presence.Read.All https://graph.microsoft.com/User.Read',
 'expires_in': 5167, 
'ext_expires_in': 5167, 
'access_token': 'eyJ0eXAiOiJKV1QiLCJub25jZSI6IjdtZlxxxxxx'}

https://docs.microsoft.com/en-us/graph/auth-v2-user Docs say I should get

{
    "token_type": "Bearer",
    "scope": "user.read%20Fmail.read",
    "expires_in": 3600,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
    "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4..."
}

Also tried scope = 'User.Read Directory.Read.All Presence.Read.All' instead of scope = 'https://graph.microsoft.com/Directory.Read.All https://graph.microsoft.com/Presence.Read https://graph.microsoft.com/Presence.Read.All https://graph.microsoft.com/User.Read'

Code that got this response:

@app.route('/auth', methods=['POST'])
def auth():
    req = request.get_json()
    code = req['code']
    redirectUrl = 'http://localhost:3000'
    scope = 'https://graph.microsoft.com/user.read https://graph.microsoft.com/Directory.Read.All https://graph.microsoft.com/Presence.Read.All'
    
    body = {
        "client_id": microsoft_client_id,
        "client_secret": client_secret,
        "grant_type": "authorization_code",
        "code": code,
        "scope": scope,
        "redirect_uri": redirectUrl
    }
    res = requests.post(
        f'https://login.microsoftonline.com/common/oauth2/v2.0/token', data=body).json()

    print(res)


Solution 1:[1]

Needed to add offline_access to scopes for refresh token via "Authorization request" in the docs. https://docs.microsoft.com/en-us/graph/auth-v2-user

"The offline_access permission is a standard OIDC scope that is requested so that the app can get a refresh token. The app can use the refresh token to get a new access token when the current one expires."

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1