我正在使用 Angular v16,我有一封由后端发送的电子邮件,其中包含一个将用户重定向到适当页面的 URL,如果用户未经过身份验证,它将把他重定向到登录页面,然后重定向到仪表板,我的问题我希望用户被重定向到电子邮件中提供的网址。 我尝试使用 router.url 访问 url,但它第一次返回
/
。
这些是路线:
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'dashboard', loadChildren: () => import('./features/dashboard/dashboard.module').then((m) => m.DashboardModule), canActivate: [SignedInGuard ] },
{ path: 'requests', loadChildren: () => import('./features/request/request.module').then((m) => m.RequestModule), data: { animation: 'dashboard' }, canActivate: [SignedInGuard ] },
{ path: 'settings', loadChildren: () => import('./features/settings/settings.module').then((m) => m.SettingsModule), data: { animation: 'settings' }, canActivate: [SignedInGuard , TrainingManagerGuard , TrainingAgentGuard , ManagerGuard] },
{ path: 'auth', loadChildren: () => import('./features/sign-in/auth.module').then((m) => m.AuthModule), data: { animation: 'auth' } },
{ path: 'access', component: AppAccessdeniedComponent },
{ path: 'notfound', component: AppNotfoundComponent , canActivate: [SignedInGuard ] },
{ path: '**', redirectTo: '/notfound' },
];
门卫签到:
export class SignedInGuard implements CanActivate {
readonly #authService = inject(AuthService);
canActivate(): Observable<boolean> {
return defer(() => {
if (!this.#authService.isLoggedIn() && !this.#authService.isLoadingSilentAuth()) {
return this.#authService.dispatchSilentAuth$().pipe(
switchMap(() => {
if (!this.#authService.isLoggedIn() && !this.#authService.isLoadingSilentAuth()) {
return of(false);
}
return of(true);
})
);
}
return of(true);
});
}
}
用户将在构造函数 authService 中重定向:
constructor() {
super();
if (environment.int){
if (this.containsJWT()) {
this.dispatchSignInJWT();
}
this.dispatchSetNewPassword();
this.dispatchIsErrorSignIn();
this.dispatchIsErrorSetPassword();
this.dispatchSignInCredentials();
this.dispatchSignInSSO();
}
if (!environment.int){
this.dispatchSignInSSO();
this.signInWithJWT$.next();
}
}
您可以看到,OnInit 会触发很多调度,例如 sso 调度方法:
dispatchSignInSSO() {
let me: UserPrivateDTO;
this.signInWithSSO$
.pipe(
tap({
next: () => this.#state.update((state) => ({ ...state, isLoadingSSOAuth: true })),
}),
switchMap((userCredentials) =>
this.signInSSO().pipe(
catchError(() => {
if (environment.int){
this.#state.update((state) => ({
...state,
isLoadingSSOAuth: false,
}));
this.messageService.add({ severity: 'warn', summary: 'Warning', detail: 'SSO login failed, Redirecting to Login Page.' });
this.redirectSignIn();
return EMPTY;
}else {
// Handle error
this.redirectAccessDenied();
this.#state.update((state) => ({
...state,
isErrorSignIn: true,
isLoadingSSOAuth: false,
}));
return EMPTY;
}
}),
),
),
takeUntilDestroyed(),
)
.subscribe({
next: (user) => {
this.sucessLogging(user);
this.redirectDashboard();
// Info message
this.displayStandardMessage(MessageType.SignedIn);
},
});
}
所以在这里,而不是使用
this.redirectDashboard();
重定向到仪表板,我想在登录守卫之前捕获URL,然后重定向到这里
在守卫上,您可以使用
location.pathname
(首选)或 location.href
捕获原始 URL
export class SignedInGuard implements CanActivate {
readonly #authService = inject(AuthService);
canActivate(): Observable<boolean> {
#authService.lastUrl = location.pathname; // <- changed here!
return defer(() => {
if (!this.#authService.isLoggedIn() && !this.#authService.isLoadingSilentAuth()) {
return this.#authService.dispatchSilentAuth$().pipe(
switchMap(() => {
if (!this.#authService.isLoggedIn() && !this.#authService.isLoadingSilentAuth()) {
return of(false);
}
return of(true);
})
);
}
return of(true);
});
}
}