sbarski / serverless-architectures-aws

The code repository for the Serverless Architectures on AWS book
http://book.acloud.guru
MIT License
154 stars 100 forks source link

Always get error in chapter-5 #6

Open vick0907 opened 6 years ago

vick0907 commented 6 years ago

Hi, thank you for this great book! it's really help us to understand serverless. But when i was practice chap5 , i build local website and setting Auth0 well. When i was try to login Auth0 with Google Account (all api is setting well whatever in js or google ) it's always show alert "There was an error" and Auth0 show "There was an error processing the login."

when i check Auth0 log dashboard ,it's only show "Success login" i don't know what's happen...can you help this issues?

thank you

parvez99 commented 6 years ago

I had a similar issue and the I was able to fix this problem by changing script tag as:

From: To :

I think it wants you to use the latest release.

parvez99 commented 6 years ago

But there's still some problem with the sign-out button, stays hidden for some reason

rdsingleton commented 6 years ago

I am having a similar problem, it is not storing the user token even though it is showing a successful login in auth0. I can see the auth0 response so i don't think it is a call back issue. Please can you help?

dolabriform commented 6 years ago

This still doesn't work, for some reason it reloads the page after the callback and clears the token. I've tested my auth0 setup by following their examples here: https://auth0.com/docs/libraries/lock/v10 And my test site works perfectly, so I know that my auth0 setup is correct. How do we fix this ?

dolabriform commented 6 years ago

I've managed to get this to work. It doesn't work with v10 of the auth0 library, so changing the script tag to the v10 library will stop it working. I switched back to the v9 library, and in the client settings in auth0 switched off OIDC Conformant in the oauth tab in advanced settings, and made sure that the client type was set to Single Page App. For some reason it didn't update. I hope that helps.

dolabriform commented 6 years ago

If you get a "unknown Algorithm" error from the lambda function, it's probably because RS256 is selected instead of HS256 in the oauth tab in advanced settings.

atomyah commented 6 years ago

modified user-controller.js to be compatible with lock v11. https://forums.manning.com/posts/list/42919.page

modified oauth tab in advanced settings to be HS256 from RS256.

still getting error "JsonWebTokenError: invalid algorithm" occurs.

03V commented 4 years ago

Hi,

I am getting the same issue still, I have pulled in the recent repo but I keep getting issues signing in.

When I use a Social provider (Google) where I am still using the Auth0 developer key to do the Authentication I get the below error:

image

In response to the above error I added Github as a social provider and added the Client ID and the Client secrete so that the app wont use the developer keys, but when I do that I get the below error

image

I have tried to resolve the issue for weeks but I have not been able to find a solution, I would greatly appreciate any help as I do not want to give up on this book

03V commented 4 years ago

So the issue was because I was using ock-9.min.js. In the index file i replaced <script src="https://cdn.auth0.com/js/lock-9.min.js"></script> with <script src="https://cdn.auth0.com/js/lock/11.22.4/lock.min.js"></script>

One thing to note is that the show function works differently in V11. Below is my implementation of user-controller.js

var userController = {
  data: {
    auth0Lock: null,
    config: null
  },
  uiElements: {
    loginButton: null,
    logoutButton: null,
    profileButton: null,
    profileNameLabel: null,
    profileImage: null
  },

  init: function(config) {
    var options = {
      container: 'hiw-login-container'
    };
    var that = this;

    this.uiElements.loginButton = $('#auth0-login');
    this.uiElements.logoutButton = $('#auth0-logout');
    this.uiElements.profileButton = $('#user-profile');
    this.uiElements.profileNameLabel = $('#profilename');
    this.uiElements.profileImage = $('#profilepicture');

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

    this.data.auth0Lock.on("authenticated", function(authResult) {
      console.log("ON activated");
      that.data.auth0Lock.getUserInfo(authResult.accessToken, function(error, profileResult) {
        console.log("Getting profile");
        if (error) {
          // Handle error
          return alert('There was an error getting the profile: ' + err.message);//This should mean that if the profile failed to load, then the events should not be wired up

        }
        localStorage.setItem('userToken', authResult.accessToken);
        that.configureAuthenticatedRequests();
        that.showUserAuthenticationDetails(profileResult);
        accessToken = authResult.accessToken;
        profile = profileResult;

        // Update DOM
      });
    });

    var idToken = localStorage.getItem('userToken');//Tries to get the token from local storage
    //This check to see if the user has logged in before and has a token stored in the webbrowser
    if (idToken) {
      this.configureAuthenticatedRequests();//Only gets called if token has already been saved
      this.data.auth0Lock.getProfile(idToken, function(err, profile) {
        if (err) {
          return alert('There was an error getting the profile: ' + err.message);//This should mean that if the profile failed to load, then the events should not be wired up
        }
        that.showUserAuthenticationDetails(profile);
      });
    }

    this.wireEvents();//For every page reload no matter the state, this method will be called
  },
  configureAuthenticatedRequests: function() {//Only called if token is in storage
    $.ajaxSetup({
      'beforeSend': function(xhr) {
        xhr.setRequestHeader('Authorization', 'Bearer ' + localStorage.getItem('userToken'));
      }
    });
  },
  showUserAuthenticationDetails: function(profile) {//Only called if token is in storage
    var showAuthenticationElements = !!profile;

    if (showAuthenticationElements) {
      this.uiElements.profileNameLabel.text(profile.nickname);
      this.uiElements.profileImage.attr('src', profile.picture);
    }
    //Hides the log in button and shows the logout and profile button
    this.uiElements.loginButton.toggle(!showAuthenticationElements);
    this.uiElements.logoutButton.toggle(showAuthenticationElements);
    this.uiElements.profileButton.toggle(showAuthenticationElements);
  },
  wireEvents: function() {
    var that = this;
    console.log("auth0Lock.show being wired up");
    this.uiElements.loginButton.click(function(e) {
//LOGIN

      var params = {
        authParams: {
          scope: 'openid email user_metadata picture'
        }
      };
        console.log("auth0Lock.show being called");
      that.data.auth0Lock.show();
    console.log("Clicked")

    //END LOGIN
    });

    this.uiElements.logoutButton.click(function(e) {
      localStorage.removeItem('userToken');

      that.uiElements.logoutButton.hide();
      that.uiElements.profileButton.hide();
      that.uiElements.loginButton.show();
    });

    this.uiElements.profileButton.click(function(e) {
      var url = that.data.config.apiBaseUrl + '/user-profile';

      $.get(url, function(data, status) {
        $('#user-profile-raw-json').text(JSON.stringify(data, null, 2));
        $('#user-profile-modal').modal();
      })
    });
  }
}
03V commented 4 years ago

Word of warning, I am a beginner so take what I have said with a grain of salt, I encourage you to look online to validate my claims

I have discovered an issue on the lambda code that causes it not to interact with the above code, the reason I believe is that the code example in the book and the repository is out of date as Auth0 has updated the way it does the authentication

Authors intended design The authors design was that when you login into the website using a social provider such as google, auth0 would return an id token and then your website would store it. Once the user clicks on the profile picture it was supposed to hit your API gateway which would then forward your Authorization token to the User-profile get resource. The user-profile lambda would then verify the id token using the node js package 'jsonwebtoken' which locally verifies the token using the secrete key and the ' hs256' algorithm (Not 100% sure about the algorithm part).

Why the incompatibility

Website end

In the above comment, the 'on' method gives you back an access token not an id token and as this blog says, you need an id token to verify but you will need an access token to get information from your social provider like email address, profile pictures etc.

Lambda end

  1. Then id token that auth0 now returns is encrypted using 'rs256' and not 'hs256' so the verify method keeps failing
  2. The request to 'https://' + process.env.DOMAIN + '/tokeninfo' no longer works

Fix

Website end

1.Request for the access token and id token

  1. When making a request to the user-profile resource on aws append the access token in the authorization header along with the id token

    Lambda

    1.Seperate the id token from the access token

  2. Verify the id token with a public key instead of the secrete key. To get the key make a call to the following url https://[your_domain].auth0.com/pem . Once you have downloaded the pem key copy the contents in between '-----BEGIN CERTIFICATE-----' and '-----END CERTIFICATE-----' (You will need to append these two back inside the code). Take extracted content and put it into an environment variable 3.Call /userinfo instead of /tokeninfo. To use /userinfo you need to pass in the access token into the Authorization header and not into the body

fix.zip