Angular 6中如何在events.addUserLoaded中实现页面重定向?
解决oidc-client中signinRedirectCallback后导航报错的问题
看起来你遇到的问题核心是回调函数中的上下文丢失,导致无法访问router实例,另外其实还有更直接的方式来处理登录后的跳转,不用依赖addUserLoaded事件,我给你分情况说明解决方案:
1. 为什么会出现Cannot read property 'navigateByUrl' of undefined?
当你在addUserLoaded中直接写普通函数时,函数内部的this并不指向你的组件实例,而是指向事件绑定的上下文,所以this.router就变成了undefined。
2. 解决方案一:用箭头函数保留组件上下文(类组件场景)
如果是Angular类组件,确保已经通过构造函数注入了Router,然后用箭头函数来绑定事件回调,这样this会一直指向组件实例:
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { UserManager } from 'oidc-client'; @Component({ selector: 'app-auth-callback', templateUrl: './auth-callback.component.html' }) export class AuthCallbackComponent implements OnInit { private userManager: UserManager; // 构造函数注入Router constructor(private router: Router) { // 初始化你的OIDC配置 const oidcConfig = { authority: '你的授权服务器地址', client_id: '你的客户端ID', redirect_uri: window.location.origin + '/auth-callback', response_type: 'code', scope: 'openid profile email' // 其他配置... }; this.userManager = new UserManager(oidcConfig); } ngOnInit(): void { // 处理登录回调 this.userManager.signinRedirectCallback().catch(err => { console.error('登录回调处理失败:', err); this.router.navigateByUrl('/login'); }); // 用箭头函数绑定事件,保留this上下文 this.userManager.events.addUserLoaded(() => { console.log('用户信息已加载'); this.router.navigateByUrl('/protected'); }); } }
3. 解决方案二:直接使用signinRedirectCallback的Promise回调(更推荐)
其实signinRedirectCallback()本身返回一个Promise,当用户信息加载完成后会resolve出User对象,完全不需要额外监听addUserLoaded事件,这种方式更简洁可靠:
ngOnInit(): void { this.userManager.signinRedirectCallback() .then(user => { console.log('登录成功,用户信息:', user); // 直接在这里跳转 this.router.navigateByUrl('/protected'); }) .catch(err => { console.error('登录回调失败:', err); this.router.navigateByUrl('/login'); }); }
4. 额外排查点
- 确保你的组件已经正确注入了
Router:Angular中要在构造函数声明private router: Router,并且所在模块已经导入了RouterModule。 - 如果是函数式组件(比如React),要确保通过
useNavigate钩子获取导航函数,并且在回调中正确调用:
import { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { UserManager } from 'oidc-client'; export default function AuthCallback() { const navigate = useNavigate(); const userManager = new UserManager({/* 你的OIDC配置 */}); useEffect(() => { userManager.signinRedirectCallback() .then(() => navigate('/protected')) .catch(err => { console.error(err); navigate('/login'); }); // 清理事件监听避免内存泄漏 return () => { userManager.events.removeUserLoaded(); }; }, [navigate]); return <div>正在处理登录...</div>; }
内容的提问来源于stack exchange,提问作者user9673479
相关产品推荐
相关产品推荐

