如何在React SPA的浏览器中保留Auth0登录状态

编程入门 行业动态 更新时间:2024-10-25 08:18:36
本文介绍了如何在React SPA的浏览器中保留Auth0登录状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

当前,当我创建路由时,我会检查Auth0方法-isAuthenticated()-确定是否返回受保护的页面或重定向至登录.但是,此状态仅存在于内存中,不会在刷新浏览器时将用户保留在其页面上,我想这样做.

Currently when I create my routes, I check an Auth0 method - isAuthenticated() - to determine whether or not to return a protected page or redirect to login. However, this state only exists in memory and does not keep a user on their page upon browser refresh and I would like to do so.

这是一个React/RR4/React Context应用程序,我的Auth0方法列在Auth.js中(如下).

This is a React/RR4/React Context app and my Auth0 methods are listed in Auth.js (below).

强烈建议将登录状态存储在localStorage中.而且,如果我将Auth0令牌存储在cookie中,由于没有设置服务器验证,因此我不确定如何验证令牌.什么条件可以检查以确保安全的数据持久性?

It is highly inadvisable to store login state in localStorage. And if I store my Auth0 tokens in cookies, I'm not sure how I would validate the tokens since there is no server validation set up. What is the correct condition to check that will enable secure data persistence?

ProtectedRoutes.jsx:

ProtectedRoutes.jsx:

<Route exact key={route.path} path={route.path} render={() => ( // CONDITION TO CHECK context.auth.isAuthenticated() ? ( <div> <routeponent /> </div> ) : <Redirect to="/login" /> )} />

Auth.js(已添加供参考):

Auth.js (added for reference):

import auth0 from 'auth0-js'; import authConfig from './auth0-variables'; class Auth { accessToken; idToken; expiresAt; tokenRenewalTimeout; auth0 = new auth0.WebAuth({ domain: authConfig.domain, clientID: authConfig.clientId, redirectUri: authConfig.callbackUrl, responseType: 'token id_token', scope: 'openid' }); constructor() { this.scheduleRenewal(); this.login = this.login.bind(this); this.logout = this.logout.bind(this); this.handleAuthentication = this.handleAuthentication.bind(this); this.isAuthenticated = this.isAuthenticated.bind(this); this.getAccessToken = this.getAccessToken.bind(this); this.getIdToken = this.getIdToken.bind(this); this.renewSession = this.renewSession.bind(this); this.scheduleRenewal = this.scheduleRenewal.bind(this); } login() { console.log('logging in!'); this.auth0.authorize(); } handleAuthentication() { return new Promise((resolve, reject) => { this.auth0.parseHash((err, authResult) => { if (err) return reject(err); console.log(authResult); if (!authResult || !authResult.idToken) { return reject(err); } this.setSession(authResult); resolve(); }); }); } getAccessToken() { return this.accessToken; } getIdToken() { return this.idToken; } getExpiration() { return new Date(this.expiresAt); } isAuthenticated() { let expiresAt = this.expiresAt; return new Date().getTime() < expiresAt; } setSession(authResult) { localStorage.setItem('isLoggedIn', 'true'); let expiresAt = (authResult.expiresIn * 1000) + new Date().getTime(); this.accessToken = authResult.accessToken; this.idToken = authResult.idToken; this.expiresAt = expiresAt; this.scheduleRenewal(); } renewSession() { this.auth0.checkSession({}, (err, authResult) => { if (authResult && authResult.accessToken && authResult.idToken) { this.setSession(authResult); } else if (err) { this.logout(); console.log(`Could not get a new token. (${err.error}: ${err.error_description})`); } }); } scheduleRenewal() { let expiresAt = this.expiresAt; const timeout = expiresAt - Date.now(); if (timeout > 0) { this.tokenRenewalTimeout = setTimeout(() => { this.renewSession(); }, timeout); } } logout() { this.accessToken = null; this.idToken = null; this.expiresAt = 0; localStorage.removeItem('isLoggedIn'); clearTimeout(this.tokenRenewalTimeout); console.log('logged out!'); } } export default Auth;

推荐答案

您可以使用静默身份验证,以在刷新浏览器时更新令牌.

You can use Silent authentication to renew the tokens on browser refresh.

专门针对您的React SPA应用

Specifically for your react SPA app

  • 在主要App组件中将状态tokenRenewed设置为false
  • 您在auth.js中已经有一个renewToken方法,因此请在componentDidMount方法中调用它
  • setup a state say tokenRenewed to false in your main App component
  • you already have a renewToken method in your auth.js so call that in componentDidMount method
componentDidMount() { this.auth.renewToken(() => { this.setState({tokenRenewed : true}); }) }

  • 更新renewToken以接受如下所示的回调cb
    • update renewToken to accept a callback cb like below
    • renewSession(cb) { this.auth0.checkSession({}, (err, authResult) => { if (authResult && authResult.accessToken && authResult.idToken) { this.setSession(authResult); } else if (err) { this.logout(); console.log(`Could not get a new token. (${err.error}: ${err.error_description})`); } if(cb) cb(err, authResult); }); }

      • 确保除非tokenRenewed为true,即除非您具有通过静默身份验证更新的有效令牌,否则不要加载App组件.
        • Make sure you don't load the App component unless tokenRenewed is true i.e. unless you have the valid tokens renewed via silent authentication
        • render() { if(!this.state.tokenRenewed) return "loading..."; return ( // Your App component ); }

          注释:

        • 您可能需要确保在应用程序"设置中设置了正确的Allowed Web Origins才能正常工作
        • 静默身份验证存在一些局限性,因为它要求在浏览器上启用第三者Cookie,并在Safari使用ITP的情况下.您应该设置一个自定义域来避免这种情况.请参阅官方auth0文档以在此处了解更多信息.
        • 有关如何安全存储令牌的更多详细信息此处
        • You may want to make sure you have the correct Allowed Web Origins set in the Application settings for this to work
        • Silent authentication has some limitations as in it requires 3rd party cookies enabled on the browser and in case ITP for Safari. You should setup a custom domain to avoid that. Refer to the official auth0 docs to learn more here.
        • More details on how to store token securely here

更多推荐

如何在React SPA的浏览器中保留Auth0登录状态

本文发布于:2023-11-01 20:32:09,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1550341.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:器中   状态   如何在   SPA   React

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!