gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 14:03:08 24 4
gpt4 key购买 nike

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

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

极不建议将登录状态存储在 localStorage 中。如果我将 Auth0 token 存储在 cookie 中,我不确定如何验证 token ,因为没有设置服务器验证。检查以实现安全数据持久性的正确条件是什么?

ProtectedRoutes.jsx:

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

Auth.js(添加以供引用):

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;

最佳答案

您可以使用Silent authentication在浏览器刷新时更新 token 。

专门针对您的 React SPA 应用

  • 在主应用组件中将状态设置为 tokenRenewedfalse
  • 您的 auth.js 中已经有一个 renewToken 方法,因此请在 componentDidMount 方法中调用该方法
componentDidMount() {
this.auth.renewToken(() => {
this.setState({tokenRenewed : true});
})
}
  • 更新renewToken以接受回调cb,如下所示
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);
});
}
  • 确保您不会加载应用组件,除非 tokenRenewedtrue,即除非您通过静默身份验证更新了有效 token
render() {
if(!this.state.tokenRenewed) return "loading...";
return (
// Your App component
);
}

注释:

  1. 您可能需要确保在应用程序设置中设置了正确的允许的 Web 来源,才能使其正常工作
  2. 无提示身份验证有一些限制,因为它需要在浏览器上启用第 3 方 Cookie,如果是 Safari 的 ITP。您应该设置一个自定义域来避免这种情况。引用auth0官方文档了解更多here .
  3. 有关如何安全存储 token 的更多详细信息 here

关于reactjs - 如何在 React SPA 的浏览器中保留 Auth0 登录状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54932922/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com