reactjs - OIDC客户端JS认证授权使用react应用
问题描述
我正在使用 OIDC 客户端使用 react 应用程序执行身份验证和授权。登录后我可以成功登录我有一个导航菜单来显示用户是否通过身份验证。
export default function NavMenu() {
const authService = new AuthService();
useSelector((state: ApplicationState) => state.oidcUser);
const dispatch = useDispatch();
const [state, setState] = useState({
isLogedIn: false
});
const [open, setOpen] = React.useState(false);
const close = () => {
setOpen(false);
};
const menuClick =() => {
setOpen(!open);
};
useEffect(() => {
authService.getUser().then((user: any) => {
if (user != null)
setState({ isLogedIn: true });
else
setState({ isLogedIn: false })
});
});
const login = () => {
authService.startAuthentication(window.location.pathname);
};
const logout = () => {
authService.logout();
};
const menuOptions = [
'Save',
'Edit',
'Cut',
'Copy',
'Paste',
];
return (<div>
<TopAppBar>
<TopAppBarRow>
<TopAppBarSection align='start'>
<TopAppBarTitle>Falcon</TopAppBarTitle>
</TopAppBarSection>
<TopAppBarSection align='end' role='toolbar'>
<div>
{(() => {
if (!state.isLogedIn) {
return (
<Button raised type="button" onClick={login}>Portal</Button>
)
} else {
return (
<div>
<Menu
open={open}
onClose={close}
onSelected={(index, item) => console.log(index, item)}>
<MenuList>
{menuOptions.map((option, index) => (
<MenuListItem key={index}>
<MenuListItemText primaryText={option} />
{/* You can also use other components from list, which are documented below */}
</MenuListItem>
))}
</MenuList>
</Menu>
<Fab onClick={menuClick} icon={<MaterialIcon icon="account_circle" />} />
</div>
)
}
})()}
</div>
</TopAppBarSection>
</TopAppBarRow>
</TopAppBar>
</div>);
}
如果我使用该方法
useEffect(() => {
authService.getUser().then((user: any) => {
if (user != null)
setState({ isLogedIn: true });
else
setState({ isLogedIn: false })
});
});
我从身份服务器获得了连接/检查会话 API 的无限循环。如果我删除该方法,则显示菜单的 if 条件 (state.isLogedIn) 将不起作用。
如何处理用户正确登录。在反应中进行 OIDC 客户端身份验证和授权的最佳方法是什么?
认证服务
export class AuthService {
public userManager: UserManager;
private user: any = null;
constructor() {
const settings = this.getClientSettings();
this.userManager = new UserManager(settings);
}
public isLoggedIn(): boolean {
return this.user != null && this.user.access_token && !this.user.expired;
}
public getUser(): Promise<User | null> {
return this.userManager.getUser().then((user) => this.user = user);
}
public login(): Promise<void> {
return this.userManager.signinRedirect();
}
public logout(): Promise<void> {
return this.userManager.signoutRedirect(this.getClientSettings().post_logout_redirect_uri);
}
public startAuthentication(returnUrl: string) {
Log.info("[AuthService] startAuthentication", returnUrl);
this.userManager.clearStaleState();
this.userManager.signinRedirect({ data: { returnUrl: returnUrl } }).then(user => this.user = user).catch(err => {
this.handleError(err);
return err;
});
}
private getClientSettings(): any {
return {
authority: "https://localhost:5001",
client_id: "Local",
redirect_uri: "https://localhost:5001/auth-callback",
post_logout_redirect_uri: "https://localhost:5001",
response_type: "code",
automaticSilentRenew: true,
scope: "profile openid email IdentityPortal.API offline_access",
//filterProtocolClaims: environment.openID.filterProtocolClaims,
loadUserInfo: true,
monitorSession: true,
silent_redirect_uri: "https://localhost:5001/silent-reniew.html",
accessTokenExpiringNotificationTime: 20, //default 60
//checkSessionInterval: 86400, //default 2000
//silentRequestTimeout: 2000,
};
}
handleError(error: any) {
Log.error(error)
}
}
解决方案
如果你想比较一些东西,也许看看我的 React 示例:
我的 AuthService 相当于我的Authenticator。如果您收到重定向循环,则可能是因为您没有调用 OIDC 客户端的 signInRedirectCallback() 方法来处理登录响应。我在您的代码中看不到对该调用的引用。
推荐阅读
- reactjs - 如何在 ReactJS 中设置对象的状态?
- vb.net - 使用 Linq 返回不同的对象
- angular - 如何使用“d3.js”库在折线图中放置圆(点)?
- spring - 检测到慢速操作:com.hazelcast.map.impl.operation.DeleteOperation 同时调用 ITopic.publish()
- dax - DAX 中的列中仅不同值的总和
- c# - TaskCanceledException 性能低下
- grep - Grep 对 S3 文件夹中的文件进行排序
- python - 致命的 Python 错误:initfsencoding:无法获取语言环境编码文件“/cm/shared/apps/anaconda2/4.5.12/lib/python2.7/encodings/__init__.py”
- wpf - 如何创建一个继承自 Thumb 的自定义控件“MyThumb”,同时用户不能设置 MyThumb 的宽度和高度?
- java - Safepoint+stats 日志,输出 JDK12 中没有 vmop 操作