React 应用程序中的 Auth0 Lock v11 未捕获“已验证”事件

Posted

技术标签:

【中文标题】React 应用程序中的 Auth0 Lock v11 未捕获“已验证”事件【英文标题】:Auth0 Lock v11 in React app not catching ‘authenticated’ event 【发布时间】:2020-04-11 14:24:12 【问题描述】:

我正在尝试在React 应用程序中实现Lock v11,并且在用户登录后,即使我点击了事件侦听器并且事件类型是authenticated,回调函数也没有被调用来处理令牌。

这是我的App.jsx,我正在初始化Auth0 Lock 并等待authenticated 事件。知道为什么我的听众不工作吗?为了进一步澄清,我在代码中输入了debuggers。用户成功登录后,我确实点击了第一个debugger,但没有点击第二个。

import React,  Component  from 'react';
import  connect  from 'react-redux';
import  bindActionCreators  from 'redux';
import  Redirect, Route, Switch, withRouter  from 'react-router-dom';
import Auth0Lock from 'auth0-lock';

// Actions
import * as appActions from '../actions/app-actions';

// Components
import Home from './home/Home';
import Public from './public/Public';

class App extends Component 

    lock = new Auth0Lock('my_auth0_client_id', 'my_domain.auth0.com', 
        auth: 
            audience: 'https://my_backend_api_url/',
            redirectUrl: 'http://localhost:3000',
            responseType: 'token id_token',
            sso: false
        
      );

    constructor(props) 

        super(props);
        this.onAuthenticated = this.onAuthenticated.bind(this);
        this.isAuthenticated = this.isAuthenticated.bind(this);

        this.onAuthenticated();
    

    onAuthenticated() 
        debugger; // After successful login, I hit this debugger
        this.lock.on('authenticated', (authResult) => 
            debugger; // But I never hit this debugger
            let expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
            sessionStorage.setItem('access_token', authResult.accessToken);
            sessionStorage.setItem('id_token', authResult.idToken);
            sessionStorage.setItem('expires_at', expiresAt);

          );
    

    isAuthenticated() 

        if(!sessionStorage.getItem("access_token") || !sessionStorage.getItem("id_token") || !sessionStorage.getItem("expires_at"))
            return false;

        const expiresAt = JSON.parse(localStorage.getItem('expires_at'));
        return new Date().getTime() < expiresAt;
    

    render() 

        const isAuthenticated = this.isAuthenticated();

        return (
            <div>
                <Switch>
                    <Route exact path="/" render=props => isAuthenticated ? <Home ...props /> : <Redirect to="/public" /> />
                    <Route path="/public">
                        <Public lock=this.lock />
                    </Route>
                </Switch>
            </div>
        );
    


function mapStateToProps(state) 

    return 
        isAuthenticated: state.app.isAuthenticated
    ;


function mapDispatchToProps(dispatch) 

    return 

        actions: bindActionCreators(appActions, dispatch)
    ;


export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));

【问题讨论】:

【参考方案1】:

authLock 对象需要在类外部初始化,因此不仅可以在索引中声明它。

然而,要在多个页面/组件中使用注销,您需要公开它。比起全局变量,我更喜欢 redux。

如果需要在一个地方使用对象

const authLockOptions: Auth0LockConstructorOptions = 
  allowSignUp: false,
  languageDictionary:  title: 'empty if you don't want title' ,
  theme: 
    primaryColor: '#333435',
    logo: 'https://your-logo-url.com',
  ,
;
const domain = process.env.AUTH0_DOMAIN || '';
const clientId = process.env.AUTH0_CLIENT_ID || '';
const authLock = new Auth0Lock(clientId, domain, authLockOptions);

export class LoginViewClass extends React.Component<LoginViewProps<BaseProps>, LoginViewState> 
  private authLock?: Auth0LockStatic;

  constructor(props: LoginViewProps<BaseProps>) 
    super(props);

    this.initializeAuthentication();
  

  private initializeAuthentication = (): void => 
    authLock.on('authenticated', (authResult: any) => 
      // call authentication function;
    );

    authLock.show();
  ;

  render(): React.ReactNode 
    return <div className='login'></div>;
  

或者,如果您需要从多个位置调用注销

// if you are using TypeScript, Auth0LockStatic is the typeof authLock object
export type YourStore = 
  authLock: Auth0LockStatic;
  // ...
;

// start the authLock when creating the DefaultStore
export const DefaultStore: YourStore = 
  authLock: new Auth0Lock(clientId, domain, authLockOptions),
  // ...
;

// in case you use reducer
const rootReducer = combineReducers(
  // other reducers
  authLock: (state = ) => state,
);

将其添加到 redux 存储后,您可以连接 mapStateToProps (react-redux) 或 useSelector (react-redux) 并随意使用它。

  authLock.on('authenticated', (authResult: any) => 
    // add your authentication functionality like dispatching the authentication
  );

  authLock.show();

【讨论】:

【参考方案2】:

this.lock.on('authenticated'... 拉到 index.js 并使 lock = new Auth0Lock... 在 index.js 中也是全局的。

或者使用 auth0 react sdk 指南:https://auth0.com/docs/quickstart/spa/react/01-login

希望对您有所帮助。

【讨论】:

我在这两个方面遇到了困难。首先,我不确定如何在 index.js 中设置 lock.on(‘authenticated’) 监听器。在那里初始化锁很容易,但不知道如何处理监听器。其次,我需要一种方法来传递锁定,以便我可以从我的组件中访问它。不知道该怎么做。也许使用 Context API Provider 方法。该应用程序已经在使用 Redux,这可能是另一种在组件中可访问锁的方法,但这似乎不是正确的方法。您介意分享一些关于如何处理 index.js 部分的代码吗? @sam - window.lock 让您可以访问 index.js 中的全局初始化,并且 authenticated 是一个在用户进行身份验证时触发的事件。这就像一个 onClick 事件。您将其安排到稍后实际发生的操作。 在 index.js 中,如果你有 var x = “foo”;然后你可以在任何 javascript 模块的任何地方通过在 x 前加上“window”来访问它。所以 window.x === “foo”【参考方案3】:

我是 Konrad,我是 Auth0 社区工程师,让我来帮你吧!查看有关 Lock 及其第一段的文档:

https://auth0.com/docs/libraries/lock/v11/configuration

看来你需要在索引文件中初始化Lock并通过这个文档判断:

https://auth0.com/docs/libraries/lock/v11/api#on-

监听器应该放在你初始化 Lock 的同一个文件中。

【讨论】:

刚刚发布的代码显示了我对authenticated 事件的初始化和监听器。出于某种原因,在用户登录后,侦听​​器被调用并且看起来事件类型是authenticated,但没有使用authResults 调用回调函数。知道为什么会发生这种情况吗?

以上是关于React 应用程序中的 Auth0 Lock v11 未捕获“已验证”事件的主要内容,如果未能解决你的问题,请参考以下文章

Auth0-lock 反应原生已弃用

Auth0 Lock 中不触发鉴权回调函数

Microsoft Teams 应用程序的 Auth0 登录

在 Android 的 Auth0 Lock 中获取 403 不允许的用户代理

React Native 中的 Auth0 刷新令牌失败并显示 401

如何使用钩子从我的 React 应用程序更新 Auth0 锁定徽标