成功登录后,用户导航至主页。但是当刷新页面时,登录页面会闪烁一秒钟。最有可能的原因是,同一页面首先在服务器端呈现,然后在客户端呈现。我将其设置为,如果用户身份验证错误,则重定向到登录页面,登录然后重定向到 authGuard 上受尊重的页面。
export const AuthGuard: CanActivateFn | CanActivateChildFn = (route, state) => {
const router: Router = inject(Router);
return inject(AuthService).checkAuthentication()
.pipe(
switchMap((isAuthenticated)=>{
if (!isAuthenticated) {
return router.createUrlTree(['auth/sign-in'], {queryParams: {param: state.url}})
}
return of(true);
})
);
}
刷新页面时,当页面在服务器端呈现时,它会得到 Authentication false 这就是它呈现登录页面然后将其发送到 clint 端的原因。但在客户端,它得到“身份验证 true”,然后显示主页(或其他页面)。但是在此期间路线不会改变。这是屏幕截图,其中服务器上的身份验证为 false,而客户端上的身份验证同时为 true。 但是,如果我关闭 SSR,登录页面根本不会闪烁。那么,有没有办法在不开启SSR模式的情况下解决这个闪烁问题呢?
app.route.ts
export const routes : Routes = [
{
path: '',
component: LayoutComponent,
canActivate: [AuthGuard],
canActivateChild: [AuthGuard],
children: [
{ path: 'home', component: DashboardComponent },
{ path: 'settings', loadChildren: () => import('./modules/settings/settings.routes') },
{ path: 'users', loadChildren: () => import('./modules/users/users.routes')},
]
},
{
path: 'auth',
loadChildren: ()=> import('./login/login.routes')
},
{ path: '', pathMatch: 'full', redirectTo: 'home' },
{ path: '**', pathMatch: 'full', redirectTo: 'home' },
];
auth.service.ts
@Injectable({ providedIn: 'root' })
export class AuthService {
private _storeService = inject(StoreService);
signIn(credentials: { username: string; password: string }): Observable<any> {
return this._httpClient.post(AUTH_API + 'User/login', credentials).pipe(
switchMap((response: any) => {
this._storeService.saveAccessToken(response.token); // save token on sessionStorage
this._storeService.saveActiveUser(response.user);
return of(response);
}),
);
}
get accessToken(): string {
return this._storeService.getAccessToken() ?? '';
}
checkAuthentication : Observable<boolean> (){
if ( !this.accessToken || AuthUtils.isTokenExpired(this.accessToken))
{
return of(false);
} else { return of(true) }
}
}
如果我需要分享更多代码,请告诉我......谢谢。
我尝试过浏览与此问题相关的角度文档/stackoverflow/google。但找不到解决这个问题的合适方法。另外,我找不到那么多功能性方法的例子。
您遇到的问题源于 Angular 中服务器端渲染 (SSR) 的性质。当服务器呈现页面时,它无法访问特定于客户端的数据,例如存储在浏览器中的身份验证令牌(例如,在 localStorage 或 sessionStorage 中)。因此服务器假设用户未经身份验证并呈现登录页面。然而,一旦客户端 JavaScript 启动,它就会将用户识别为已通过身份验证(借助令牌)并快速重定向到目标页面。这会导致您正在观察的登录页面短暂闪烁。
您可以考虑在服务器和客户端之间实现共享身份验证状态。这将涉及在初始请求中(通过 cookie)将身份验证令牌发送到服务器。您需要调整身份验证流程以验证服务器端的令牌并使用已通过身份验证的用户初始化应用程序。