Complete idp login doesn't return refreshToken



  • Hi,

    I completing a login after a google login from our own login page with this endpoint (https://fusionauth.io/docs/v1/tech/apis/identity-providers/google#complete-the-google-login). I don't understand why I don't receive a refreshToken.
    The only condition mentionned in the doc is the presence of the applicationId which we did provided, it's event present in the returning payload:

    from the doc:

    Because a refresh token is per user and per application, this value will only be returned when an applicationId was provided on the login request.

    Return payload received from FA:

    {
      "user" : {
        "id" : "userId"
        "active" : true,
        "firstName" : "Stefan",
        "registrations" : [
          {
            "lastLoginInstant" : 1595002474203,
            "applicationId" : "1e85ab7d-7e27-4729-b61f-fdb9f9ce6d6e",
            "tokens" : {
              "Google" : "googles token"
            },
            "insertInstant" : 1595002474186,
            "id" : "82f88268-dffb-4a81-8323-ec28fde87754",
            "verified" : true,
            "usernameStatus" : "ACTIVE"
          }
        ],
        "tenantId" : "db507f75-2f84-2e46-5f8c-bc9913a3880b",
        "usernameStatus" : "ACTIVE",
        "verified" : true,
        "twoFactorDelivery" : "None",
        "imageUrl" : "https:\/\/lh5.googleusercontent.com\/-82xeGvvebOk\/AAAAAAAAAAI\/AAAAAAAAAAA\/AMZuucka1J5muJev4xFKfUtD84QfCWPM-w\/s96-c\/photo.jpg",
        "insertInstant" : 1595002474143,
        "twoFactorEnabled" : false,
        "passwordLastUpdateInstant" : 1595002474175,
        "fullName" : "Stefan and his lastname",
        "lastName" : "last name",
        "email" : "stefanemail@gmail.com",
        "lastLoginInstant" : 1595002474203,
        "passwordChangeRequired" : false
      },
      "token" : "valid jwt token"
    }
    

    Is there some other condition needed to get the refreshToken ?


    Some information:

    instance: https://swift-tech.fusionauth.io/ running 1.17.4

    Here's the config of the application in case it helps:

    2d10a045-c031-40b2-949a-7a72be5b2455-image.png Screen Shot 2020-07-17 at 19.48.45



  • @dan could you have a quick run at this? I'm always reluctant to file a bug until I've cleared the possible obvious reasons



  • Hi,

    After nosing around a bit, it looks like if you use the google identity provider, we don't request the refresh token, only the access token.

    You can try to use the OIDC identity provider against google instead: https://fusionauth.io/docs/v1/tech/identity-providers/openid-connect/ You can request the offline_access scope and if Google returns a refresh token based upon that scope you could store it using a lambda, in the registration.data field, for example, and then retrieve it later.

    Of course, you can also file an issue explaining what you'd prefer to happen with the google identity provider. There are some limits google places on refresh tokens which may impact implementation: https://developers.google.com/identity/protocols/oauth2/openid-connect#refresh-tokens



  • Hi @dan ,
    Thanks for looking into it. I think there is a misunderstanding, I'm not looking to obtain a refresh token from google but one issued by FusionAuth.

    I don't need google's refresh token for this use case, I let FA retrieve the info it needs once and that's it, I don't need to have further access to google's resources.

    then, as an application resource server, I just check the tokens provided by FA, without even knowing if the user registered with an idp or not.

    I'm looking for the refresh token issued by FA, that I can later exchange for a new AccessToken (still issued by Fa, not Google)

    🔝 this refreshtoken : https://fusionauth.io/docs/v1/tech/apis/identity-providers/google#response-body-4



  • Ah, thanks for the explanation.

    Are you passing a scope parameter to FusionAuth?

    From the applications docs:

    When enabled, FusionAuth will return a refresh token when the offline_access scope has been requested. When this setting is disabled refresh tokens will not be generated even if the offline_access scope is requested.

    I was able to do this locally by using this url: `http://localhost:9011/oauth2/authorize?client_id=9d995316-d175-4e74-b08b-4073de0eb44a&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Foauth-redirect&scope=offline_access

    Then, when I complete signing in via google, I see a refresh_token in the response.

    If that doesn't work for you, please let me know as it may be a bug.



  • Thanks again for your answer @dan ,

    Are you passing a scope parameter to FusionAuth?

    Not I'm not passing any scope, because the endpoint I'm using doesn't accept one: https://fusionauth.io/docs/v1/tech/apis/identity-providers/google#complete-the-google-login

    Are you saying that I must first have a flow through the oauth2/authorize endpoint?

    From what I understand from the doc of the complete-the-google-login it isn't necessary, I should be able to use that endpoint to create a user

    For example, if you built your own login page, you could add a Login with Google button and complete the Google authentication. When you complete the Google authentication you will have been returned an id token from Google. Using this API you can pass that id token returned from Google to FusionAuth and we will complete the login workflow and reconcile the user to FusionAuth.
    The user does not need to exist yet in FusionAuth to utilize this API.

    So If my user doesn't exist yet in fusionauth, I can't have provided a scope before hand.

    I'm starting to think I may misunderstand what this complete login endpoint objective is.
    I'm building my own login page, and letting users auth themselves through google and then I silently register them to my fusionauth instance. User never hears about fusionauth. Does that scenario fits what /api/identity-provider/login offers ?



  • I'm starting to think I may misunderstand what this complete login endpoint objective is.

    I think I'm the one who is misunderstanding things 🙂 Yes, you should be able to build your own login pages to auth directly with google, and yes, you should get the refresh_token returned. I didn't follow what you were attempting to do, I thought you were using the google form provided by FusionAuth (which is what I tested and which returns a refresh_token if you provide the scope).

    This sure looks like a bug because the refresh_token should be returned according to the docs. At the very least it is a doc bug, because the noJWT parameter doesn't state that the refreshToken will be returned if noJWT = false:

    When this value is set to true a JWT will not be issued as part of this request. The response body will not contain the token field, and the access_token and refresh_token cookies will not be written to the HTTP response

    But the response body states a refreshToken will be returned:

    The refresh token that can be used to obtain a new access token once the provide one has expired.
    
    Because a refresh token is per user and per application, this value will only be returned when an applicationId was provided on the login request.
    

    Can you please file a bug? https://github.com/fusionauth/fusionauth-issues/issues


Log in to reply