17
votes

I am doing LinkedIn authentication with auth0 in a react app. I have set localhost:3000/upload in callback urls in settings, hopping that after users login at localhost:3000/login, they would be redirected to localhost:3000/upload. However, I always get this error: url localhost:3000/login is not in the list of callback urls. Why would auth0 expect to return to the page where you just logged in after logging in. Shouldn't it be some different url. It just does not make sense to me.

Edit:

export default class AuthService {
  constructor(clientId, domain) {
    // Configure Auth0
    const options = {
      allowedConnections: ['linkedin'],
      auth: {
        params: {responseType: 'code'}
      }
    };  
    this.lock = new Auth0Lock(clientId, domain, options)
    // Add callback for lock `authenticated` event
    this.lock.on('authenticated', this._doAuthentication.bind(this))
    // binds login functions to keep this context
    this.login = this.login.bind(this)
    this.loggedIn = this.loggedIn.bind(this)
  }

  _doAuthentication(authResult){
    // Saves the user token
    console.log(authResult);
    this.setToken(authResult.idToken)
    this.lock.getProfile(authResult.idToken, (error, profile) => {
      if (error) {
        console.log('Error loading the Profile', error)
      } else {
        console.log(profile)
      }
    })
  }
//....
6

6 Answers

16
votes

Please ensure two things:

1). In your react app code

 responseType: 'code'

2). On the Auth0 dashboard, under Settings -> Allowed Callback URLs put your callback entry (localhost:3000/upload) - which I think you have done but just in case.

enter image description here

Let me know if you are still having problems.

2
votes

To cause a redirect to a different URL after a successful authentication, you need to provide the redirectUrl to Lock, like this:

// Configure Auth0 const options = { allowedConnections: ['linkedin'], auth: { responseType: 'code', redirectUrl: 'http://localhost:3000/upload' } };
this.lock = new Auth0Lock(clientId, domain, options)

(Also notice that the responseType option goes under auth, not under auth.params.)

If you do the redirect, you won't reach the event handler you defined in your login page. You will need to either add an event handler in your destination page (and use responseType:token) or handle authentication results in your server code (this is what you will normally be doing if you are requesting a responseType: code).

2
votes

Make sure that there is no special hidden characters or space between the commas between the URLs when you paste it into the Auth0 Setting site. I didn't realise about this util I put every urls into Vim to check and see that there are such above cases

1
votes

In the call to AuthProvider, make sure to use to same callback url as the one in Auth0 settings:

const uri='http://localhost:3000/upload';

        <Auth0Provider
        domain={domain}
        clientId={clientId}
        redirectUri={uri}>
1
votes

I had similar issue "callback URL mismatch" and resolved it by running the application over https with a trusted certificate.

Here is a snippet from Auth0 applications settings section about callback URL, which says "Make sure to specify the protocol (https://) otherwisw the callback may fail in some cases."

enter image description here

0
votes

the reason why you should set the callback Url in auth0 settings, because any one can use your client id and send request to google or linkedin, get the response to anywhere they set. but with this setting only you can access that response.

once your app is authorized to pull the data from linkedin, linkedin will send the data to where you specified. you should create a page to handle the response from Linkedin server. Let's name that page callback.js and this will be an example of response object.

accessToken: "hNuPLKTZHiE9_lnED0JIiiPNjlicRDp"
   appState: null
   expiresIn: 7200
   idToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik5FRXdSVUl5TURVeE4wSkJPRFZEUlRKRU1EVkZNemsxTXpNNU5VTXlNRGt6T0VWQlJqUkZRUSJ9.eyJodHRwOi8vbG9jYWxob3N0OjMwMDAvcm9sZSI6InNpdGVPd25lciIsImdpdmVuX25hbWUiOiJvbWFyIiwiZmFtaWx5X25hbWUiOiJpYm8iLCJuaWNrbmFtZSI6Im9tYXJpYm8xOTgyIiwibmFtZSI6Im9tYXIgaWJvIiwicGljdHVyZSI6Imh0dHBzOi8vbGg1Lmdvb2dsZXVzZXJjb250BQUFBQUkvQUFBQUFBQUFBQUEvQUNIaTNyLTEwLTEyVDIyOjU4OjAxLjgzM1oiLCJpc3MiOiJodHRwczovL3BvcnRmb2xpby15aWxtYXouYXV0aDAuY29tLyIsInN1YiI6Imdvb2dsZS1vYXV0aDJ8MTE0MDY0NTA2ODI2OTgwNTA5ODY3IiwiYXVkIjoiUEdVY242RjRRS21PRkJhb1k0UFdCeWpjVzIyT09vNGMiLCJpYXQiOjE1NzA5MjEwODIsImV4cCI6MTU3MDk1NzA4MiwiYXRfaGFzaCI6InN0R1l5SnJaMHNnbVYzSWNLWjlPeFEiLCJub25jZSI6InRrOV95b096enRmVThVVjFVMlVFR3IyMW5ORW5abjk4In0.TYS7mM8N2d7jEHFdWQGTSeAAUaDt4-0SMUG3LrcQ1r3xzY0RMGsUsEszj5xqk1GE0cIlFS10xCOYKsuHSwsFLomC1EbLjntjkledHtfD0MW84cMoXN6a-x-1-bNwl3lMYJ98qklTrNvTvkQJ6DWhei3hJ8rs8dnbNyCfckNVU6ptJU-9ef1DwWfHRomW5LQ6WSDRHZScW697gdgBEMU-Nd2SddyHhQe0kVh6lKdcbnskEAyCJLE07jfM40RQI_8LJouFcpoyImcXSDZlKv90tYfVDq9_TwE3GNaSz5I5snn0457oCgz0vuX0JoCUiaDuTIX7XiyXnozW_DxGMuhk4w"
   idTokenPayload: {http://localhost:3000/role: "siteOwner", given_name: "me", family_name: "you", nickname: "nck", name: "nm", …}
   refreshToken: null
  scope: null
   state: "xkEbffzXbdOYPLkXOUkrQeb0Jysbnlfy"
   tokenType: "Bearer"
//THIS CODE IS FOR NEXT.JS9
//auth.js
class Auth0 {
  constructor() {
    this.auth0 = new auth0.WebAuth({
      domain: "portfolio-ys.auth0.com",
      clientID: "PGUWJQKmOFBaoY4PWByjcW22OOo4c",
      redirectUri: "http://localhost:3000/callback",
      responseType: "token id_token",
      scope: "openid profile"
    });

     this.handleAuthentication = this.handleAuthentication.bind(this);
  }
     //there are too many methods are defined here i put only relevant ones
    handleAuthentication() {
        return new Promise((resolve, reject) => {
          this.auth0.parseHash((err, authResult) => {
            console.log(authResult);
            if (authResult && authResult.accessToken && authResult.idToken) {
              this.setSession(authResult);
              resolve();
            } else if (err) {
              reject(err);
            }
          });
        });
      }

setSession function is where you set the cookies based on response object. I use js-cookie package to set the cookie.

    setSession(authResult) {
        const expiresAt = JSON.stringify(
          authResult.expiresIn * 1000 + new Date().getTime()
        );
        Cookies.set("user", authResult.idTokenPayload);
        Cookies.set("jwt", authResult.idToken);
        Cookies.set("expiresAt", expiresAt);
      }


}
const auth0Client = new Auth0();
export default auth0Client;


callback.js
import React from "react" 
import auth0Client from "./auth0"
import {withRouter} from "next/router"

 class Callback extends React.Component{
    async componentDidMount(){
        await auth0Client.handleAuthentication()
        this.props.router.push('/')
    }
    render() {
        return (

                    <h1>verifying logging data</h1>

        )
    }
}

export default withRouter(Callback) //this allows us to use router