Search code examples
reactjsauth0auth0-lock

Where to initialize Auth0 lock in a react app


I'm implementing Auth0 Lock 11 in my react app. The app is also using Redux and react-router-dom.

I'm trying to follow the documentation here but having trouble getting initializing Lock properly. I'm also confused about how to check if a user is authenticated or not. Before I was using Lock v9 and things seemed more intuitive.

General behavior that I'm trying to implement is this:

  • All of the app will be protected except for Public component
  • If a user tries to access a protected section, I will Redirect user to Public

Here's what I have so far. This file is where I keep all Auth0 code:

import Auth0Lock from 'auth0-lock';

export default class Auth { 

    lock = new Auth0Lock('my_client_id', 'mydomain.auth0.com', {

            auth: {
                audience: 'https://myapi.com',
                redirectUrl: 'http://localhost:3000',
                responseType: 'token id_token',
                params: {
                    scope: 'openid email profile'
                }
            }
        }
    ).on('authenticated', function(authResult) {

        if (authResult && authResult.accessToken && authResult.idToken) {
            this.setSession(authResult);
            // use authResult.idTokenPayload for profile information
        }
    });

    setSession(authResult) {

        debugger
    }

    login() {

        this.lock.show()
    }
}

So, here are my questions:

  1. Where do I initialize Lock? In App.js?
  2. If the user is not authenticated, he gets redirected to Public component. How do I access the login() function from Public? I understand that I can simply reference it in the component but will that not re-initialize Lock all over again?

Solution

  • My preferred approach for situations like this is to wrap the App component in an AuthWrapper component that provides AuthContext. Something like this:

    import Auth from "./Auth"
    
    const AuthContext = React.createContext({})
    
    class AuthWrapper extends React.Component {
      constructor(props) {
        super(props)
        this.auth = new Auth()
      }
    
      login = () => {
        this.auth.login()
      }
    
      render() {
        return (
          <AuthContext.Provider value={{ login: this.login }}>
            {this.props.children}
          </AuthContext.Provider>
        )
      }
    }
    
    const SomeComponent = () => {
      const { login } = useContext(AuthContext)
      return <button onClick={login}>Show Auth</button>
    }
    

    If this isn't clear let me know.