我一直在尝试调整react-openidconnect 以消除单击的需要,因为我需要应用程序在未经身份验证时自动重定向到身份服务器。
但无论我尝试什么,我总是以无限循环的重定向告终。我尝试将组件重构为无状态函数,但它不断被重新渲染。
import React from 'react';
import { UserManager, User } from 'oidc-client';
import { oidcSettings } from '../../AppSettings';
interface Props {
OidcSettings: any;
userLoaded?: (user: User) => void;
userunLoaded?: () => void;
renderNotAuthenticated: () => JSX.Element;
children: React.ReactNode;
}
export const Authenticate = (props: Props) => {
const [isAuthenticated, setIsAuthenticated] = React.useState(false);
const userManager = new UserManager(oidcSettings);
const onUserLoaded = (user: User) => {
setIsAuthenticated(true);
if (props.userLoaded !== undefined) props.userLoaded(user);
};
const onUserUnloaded = () => {
setIsAuthenticated(false);
if (props.userunLoaded !== undefined) props.userunLoaded();
};
const signin = () => {
userManager
.signinRedirect()
.then(function () {
console.log('signinRedirect ok');
})
.catch(function (err) {
console.log('signinRedirect error:', err);
});
};
React.useEffect(() => {
const doCheckAuth = async () => {
userManager.events.addUserLoaded(onUserLoaded);
userManager.events.addUserUnloaded(onUserUnloaded);
let user = await userManager.getUser();
if (user !== null && user !== undefined) {
console.info('doCheckAuth - User found from userManager, isAuthenticated:', isAuthenticated);
onUserLoaded(user);
} else if (window.location.href.includes('#id_token')) {
console.info('doCheckAuth - Found #id_token in location.href');
try {
user = await userManager.signinRedirectCallback(window.location.href);
if (user !== null && user !== undefined) {
console.info('doCheckAuth - Found user from signinRedirectCallback');
}
window.history.replaceState({}, '', '/');
} catch (err) {
console.error('Error signinRedirectCallback: ', err);
}
} else console.info('doCheckAuth - nothing to do');
};
if (!isAuthenticated) doCheckAuth();
}, []);
return isAuthenticated ? <div>{props.children}</div> : <div onClick={signin}>{props.renderNotAuthenticated()}</div>;
};
由于原始组件总是在一段时间内呈现 NotAuthenticated 元素,到目前为止我发现的唯一解决方法是设置超时以模拟给定时间后的点击,但我简直不敢相信这个可怕的解决方案是只有一个。
我对 React 很陌生,所以有人能提出解决方案吗?
(我也尝试简单地从 node_modules src 文件夹中复制相同的代码,不添加任何内容,作为添加逻辑的起点,但无限循环又出现了)