Angular用户登录功能异常,配合Node.js实现未获取userid自动登出如何操作?
实现方案
你需要分别在后端Node.js接口层和前端Angular应用层做逻辑补充,完整实现需求:
1. 后端Node.js接口逻辑优化
先从接口源头拦截无userid的异常登录场景,避免给无效用户下发有效token,在你现有的密码校验通过、生成token的逻辑前,增加userid存在性判断,调整后代码如下:
connection.query(sql,[email,password], function (error, results, fields) { if (error) { res.send({ "code":400, "failed":"error ocurred" }) }else{ if(results.length >0){ console.log(results.length); if(results[0].password == password){ // 新增:判断userid是否存在 if(!results[0].id) { return res.send({ "code":204, "success":"用户信息异常,登录失败" }); } const payload = { admin: email }; var token = jwt.sign(payload, app.get('superSecret'), { expiresIn : 60*60*24 // expires in 24 hours }); res.send({ "code":200, token : token, result : email, username: results[0].fullname, clientid : results[0].clientid, userid: results[0].id, "success":"1" }); } else{ res.send({ "code":204, "success":"Email and password does not match" }); } } else{ res.send({ "code":204, "success":"Email does not exits" }); } } });
注意:当前你的后端代码直接明文比对密码存在安全风险,建议使用bcrypt等加密库对密码做哈希存储和校验。
2. 前端Angular应用逻辑补充
需要做三层校验,覆盖所有异常场景:
2.1 登录接口回调处即时校验
调用登录接口拿到返回结果后,先判断是否返回有效userid,若不存在直接触发登出逻辑:
// 你的登录服务调用处代码示例 this.loginService.login(loginForm.value).subscribe(res => { if(res.code === 200) { // 新增userid校验 if(!res.userid) { this.logout(); this.message.error('用户信息异常,请重新登录'); return; } // 正常登录逻辑:存储token、用户信息、跳转首页 localStorage.setItem('token', res.token); localStorage.setItem('userid', res.userid); this.router.navigate(['/dashboard']); } }) // 封装公共登出方法 logout() { // 清空所有本地存储的登录信息 localStorage.removeItem('token'); localStorage.removeItem('userid'); localStorage.removeItem('username'); // 跳转登录页 this.router.navigate(['/login']); }
2.2 新增路由守卫做全局校验
避免用户直接通过地址栏跳过登录页访问内部页面,每次路由跳转前都校验本地是否存储有效userid:
// auth.guard.ts 代码示例 @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate { constructor(private router: Router) {} canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): boolean | UrlTree { const userid = localStorage.getItem('userid'); const token = localStorage.getItem('token'); if(userid && token) { return true; } // 无有效登录信息,触发登出 localStorage.clear(); return this.router.createUrlTree(['/login']); } } // 路由配置中绑定守卫 const routes: Routes = [ { path: 'login', component: LoginComponent }, { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] // 所有需要登录的路由都绑定该守卫 } ]
2.3 新增HTTP拦截器做请求校验
如果后续后端接口对无有效userid的请求返回401状态码,可通过拦截器统一触发登出逻辑,避免每个接口单独处理:
// auth.interceptor.ts 代码示例 @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private router: Router) {} intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { return next.handle(request).pipe( catchError((error: HttpErrorResponse) => { if (error.status === 401) { localStorage.clear(); this.router.navigate(['/login']); } return throwError(() => error); }) ); } }
内容的提问来源于stack exchange,提问作者kate moss
相关产品推荐
相关产品推荐

