Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth0 Lock API v9 is deprecated #9

Open
johnsgp opened this issue Jan 16, 2018 · 15 comments
Open

Auth0 Lock API v9 is deprecated #9

johnsgp opened this issue Jan 16, 2018 · 15 comments

Comments

@johnsgp
Copy link

johnsgp commented Jan 16, 2018

I have been having trouble using Auth0 with a new account created today. A slightly older account created a month or so ago (5 December 2017) works fine.

The error is that Auth0 Lock is trying (and failing) to do an HTTP GET on

<my-auth0-domain>/user/ssodata

In the Auth0 logs of the older account (where it works), I have a warning entry with a deprecation notice:

SSOdata endpoint: This feature is being deprecated. Please refer to our documentation to learn how to migrate your application.

I followed the descriptions for migration in the documentation combined with the SPA with jQuery Quickstart, and got it to work with centralized login but I cannot be sure this will work with the rest of the chapter and/or book.

In particular, centralized login provides an access token and ID token rather than a user token, and logout does not cleanly eliminate all session data (some cookies remain which 'remember' who last logged in).

It would help to know whether anyone else has a better solution or confirmation that I'm on the right track.

@kay-is
Copy link

kay-is commented Feb 20, 2018

I had the same issues with Lock 9, couldn't get it to work.

I used Lock version 11.2

<script src="https://cdn.auth0.com/js/lock/11.2/lock.min.js"></script>

And rewrote the user-controller.js

window.userController = {
  data: {
    auth0Lock: null,
    config: null
  },

  uiElements: {
    loginButton: null,
    logoutButton: null,
    profileButton: null,
    profileNameLabel: null,
    profileImage: null
  },

  init(config) {
    {
      const { uiElements } = this;
      uiElements.loginButton = $("#auth0-login");
      uiElements.logoutButton = $("#auth0-logout");
      uiElements.profileButton = $("#user-profile");
      uiElements.profileNameLabel = $("#profilename");
      uiElements.profileImage = $("#profilepicture");
    }

    {
      const { data } = this;
      data.config = config;
      data.auth0Lock = new Auth0Lock(
        config.auth0.clientId,
        config.auth0.domain
      );
    }

    {
      const accessToken = localStorage.getItem("userToken");
      if (accessToken) {
        this.configureAuthenticatedRequests();
        this.data.auth0Lock.getUserInfo(accessToken, (error, profile) => {
          if (error) return alert("Auth0 error: " + error.message);
          this.showUserAuthenticationDetails(profile);
        });
      }
    }

    this.wireEvents();
  },

  configureAuthenticatedRequests() {
    $.ajaxSetup({
      beforeSend(xhr) {
        xhr.setRequestHeader(
          "Authorization",
          "Bearer " + localStorage.getItem("userToken")
        );
      }
    });
  },

  showUserAuthenticationDetails(profile) {
    const showAuthenticationElements = !!profile;

    if (showAuthenticationElements) {
      const { profileNameLabel, profileImage } = this.uiElements;
      profileNameLabel.text(profile.nickname);
      profileImage.attr("src", profile.picture);
    }

    {
      const { loginButton, logoutButton, profileButton } = this.uiElements;
      loginButton.toggle(!showAuthenticationElements);
      logoutButton.toggle(showAuthenticationElements);
      profileButton.toggle(showAuthenticationElements);
    }
  },

  wireEvents() {
    const { auth0Lock, config } = this.data;

    auth0Lock.on("authenticated", ({ accessToken }) =>
      auth0Lock.getUserInfo(accessToken, (error, profile) => {
        auth0Lock.hide();
        if (error) return alert("Auth0 error:" + error);

        localStorage.setItem("userToken", accessToken);
        this.configureAuthenticatedRequests();
        this.showUserAuthenticationDetails(profile);
      })
    );

    {
      const { loginButton, logoutButton, profileButton } = this.uiElements;

      loginButton.click(() =>
        auth0Lock.show({ auth: { params: { scope: "openid profile" } } })
      );

      logoutButton.click(() => {
        localStorage.removeItem("userToken");
        logoutButton.hide();
        profileButton.hide();
        loginButton.show();
        auth0Lock.logout({ returnTo: "http://127.0.0.1:8100" });
      });

      profileButton.click(() => {
        const url = config.apiBaseUrl + "/user-profile";
        $.get(url, data => {
          $("#user-profile-raw-json").text(JSON.stringify(data, null, 2));
          $("#user-profile-modal").modal();
        });
      });
    }
  }
};

Also, I added http://127.0.0.1:8100 to all the domain/callback/url settings for the Auth0 client I created.

@kay-is
Copy link

kay-is commented Feb 21, 2018

Seems like the userToken from the book is split up into idToken and accessToken.

I tried to go with one of them, but it didn't work.

You need the idToken to do the jwt.verify in the user-profile lambda function.

The POST /tokeninfo endpoind of Auth0 seems to be gone and now you need to use GET /userinfo to get the profile information. This call needs to have the accessToken inside the Authorization header.

So I sent both tokens to the user-profile lambda, one for auth, one for userinfo.

@johnsgp
Copy link
Author

johnsgp commented Feb 21, 2018

@kay-is Thanks for verifying! I did the same but unfortunately did so by using two headers (Authorization and AccessToken) which meant that a number of other changes (including CORS) were required later in the book as well. It might be possible to concatenate the two tokens and put them both into the Authorization header to keep things simpler, which would then involve a bit of parsing in the Lambda functions.

@kay-is
Copy link

kay-is commented Feb 21, 2018

Seems like the access token is only used for the Auth0 management API. (https://auth0.com/docs/tokens)

Maybe it's not needed later?

@johnsgp
Copy link
Author

johnsgp commented Feb 21, 2018

It's needed wherever you want to use the custom authorizer.

@kay-is
Copy link

kay-is commented Feb 21, 2018

As far as I can tell, the custom authorizer only uses the idToken, not the accessToken.

@johnsgp
Copy link
Author

johnsgp commented Feb 21, 2018

@kay-is My apologies - you are correct. As you already said, the access token is only needed for calls to the Auth0 API and I only found one example in the book - the user profile which you correctly noted changed from tokeninfo to userinfo.

@zhammer
Copy link

zhammer commented Mar 1, 2018

@johnsgp thanks for raising this issue. just ran into the same thing.
@kay-is your solution worked for me!

@sbarski wrote an amazing book, but all the technologies used are changing so rapidly, i'm worried it won't be that useful in the future (if not actively updated).

@zhammer
Copy link

zhammer commented Mar 4, 2018

Anyone having an issue getting idToken in the callback from auth0Lock.on? My idToken in the authResult callback object is always set to null.

{
  "accessToken": "M__x7H6VNlkeq2MPcynmgBPHG6QL6IrB",
  "appState": null,
  "expiresIn": 7200,
  "idToken": null,
  "idTokenPayload": null,
  "refreshToken": null,
  "scope": "openid profile",
  "state": "LPxQc-Pazmwh~HpmLT101yL9~EDIE_rE",
  "tokenType": "Bearer"
}

I'm getting pretty lost in a bunch of Auth0 github issues and Auth0 documentation pages. Curious if either of you (@johnsgp & @kay-is) figured this out.

@zhammer
Copy link

zhammer commented Mar 4, 2018

Perhaps this is the issue -- that audience is set to an endpoint rather than a custom API? https://auth0.com/docs/tokens/access-token#access-token-format

Though it does seem odd given the Auth0 doc warning:
Remember always that the client should not depend on the Access Token to be any specific format, but instead treat the Access Token as opaque. It is meant only for the API.

@zhammer
Copy link

zhammer commented Mar 4, 2018

Here's my solution. You need to specify responseType to be id_token AND token. (This may be what @kay-is wrote in a previous post, but still was a bit confused.)

            loginButton.click(() =>
                              {
                                  auth0Lock.show({ auth: {
                                      params: {
                                          responseType: 'id_token token',
                                          scope: 'openid profile'
                                      }
                                  } });
                              }
                             );

@johnsgp
Copy link
Author

johnsgp commented Mar 5, 2018

Hi @zhammer, yes I specified both id_token and token as the response type, as you've discovered.

@pault2k14
Copy link

for some reason id_token didn't seem to be getting passed through from auth0Lock.show({ auth: { params: { responseType: 'id_token token', scope: 'openid profile' }

So I had to update my auth0 client options under advanced settings to disable OIDC Conformant that allowed the id_token to finally be returned.

After the id_token was coming through I began getting an invalid algorithm error from the user-profile lambda and i had to go back to auth0 client advanced settings and set JsonWebToken Signature Algorithm from RS256 to HS256, finally it's working!

@o9830385-nwytgnet
Copy link

sorry the explanations and solutions presented here are too convoluted for me

could someone post a complete set of the updated code listings please that i am supposed to use in each chapter to get the examples in the book to work now that cdn.auth0.com/js/lock-9.min.js is no longer supported ?

thank you

@corhyam
Copy link

corhyam commented Apr 2, 2021

When I update my auth0 client options advanced settings to disable OIDC Conformant, the id_token finally stored in “Local Storage”. But I try to set "JSON Web Token (JWT) Signature Algorithm" from RS256 to HS256, It's still not working. And then, I go to Api gateway, and add the 'access token' in the Access-Control-Allow-Headers, finally it's working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants