首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不使用LocalStorage或Cookie的Auth防护装置

不使用LocalStorage或Cookie的Auth防护装置
EN

Stack Overflow用户
提问于 2022-07-06 02:46:56
回答 2查看 217关注 0票数 1

我用角度实现了auth保护,但我没有访问本地存储或cookie来检查用户是否经过身份验证,而是有一个API端点,如果存在一个仅包含附加到请求的JWT的httponly cookie,则返回200 OK,否则将返回401 Unauthorized

这是我尝试过的

代码语言:javascript
复制
// auth.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root',
})
export class AuthService {
  constructor(
    private httpClient: HttpClient,
  ) {}

  login(username: string, password: string) {
    return this.httpClient.post('/users/login', { username, password });
  }

  isLoggedIn(): boolean {
    this.httpClient.get('/users/check').subscribe({
      next: (data) => {
        return true;
      },
      error: () => {
        return false;
      },
    });

    return false;
  }
}
代码语言:javascript
复制
// auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable({
  providedIn: 'root',
})
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(): boolean {
    if (!this.authService.isLoggedIn()) {
      this.router.navigate(['login']);
      return false;
    }

    return true;
  }
}
代码语言:javascript
复制
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './login/login.component';
import { LayoutComponent } from './layout/layout.component';
import { ProjectsComponent } from './projects/projects.component';
import { AuthGuard } from './core/auth/auth.guard';

const routes: Routes = [
  {
    path: '',
    component: LayoutComponent,
    canActivate: [AuthGuard],
    children: [{ path: 'projects', component: ProjectsComponent }],
  },
  { path: 'login', component: LoginComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

问题发生在用户登录和身份验证cookie设置之后,isLoggedIn()函数仍然返回false,从而将用户重定向回登录页面。我的猜测是,这与我错误地处理来自httpclient的可观察到的内容有关,并在请求完成之前将其发送给return false;

任何帮助都是感激和感谢的,提前!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-06 03:30:35

这是一个经典的异步处理问题,以及一些功能范围的理解.

当您这样做时,可以看到两个主要问题:

代码语言:javascript
复制
isLoggedIn(): boolean {
    this.httpClient.get('/users/check').subscribe({
      next: (data) => {
        return true; // issue 02
      },
      error: () => {
        return false;  // issue 02
      },
    });

    return false; // issue 01
  }

  • 问题01:您的函数只/总是返回false,因为这是isLoggedIn函数作用域中唯一的返回语句。(经典异步问题)

  • 问题02:调用订阅的回调函数,但不使用它们的返回值。(对功能范围界定的理解提出异议)。问题是,标记为“问题02”的return的i属于订阅回调的范围,而不是isLoggedIn函数的范围.

要解决这一问题:

  1. 您应该返回可观察到的结果,使用管道将结果转换为true/false,而不是订阅:

代码语言:javascript
复制
isLoggedIn() {
  return this.httpClient.get('/users/check').pipe(
    map(() => true),
    catchError(() => of(false))
  )
}

  1. 从您的警卫(在那里您有一个类似的问题,在您的服务),您也没有订阅,并相信订阅将由调用者(角度内部):

代码语言:javascript
复制
canActivate() {
  return this.authService.isLoggedIn().pipe(take(1), tap(loggedIn => {
    if (!loggedIn) this.router.navigate(['login']);
  }));
}
票数 2
EN

Stack Overflow用户

发布于 2022-07-06 06:11:03

试试这个,它对我有用。

在isLoggedIn函数中:

代码语言:javascript
复制
isLoggedIn(): boolean {
        return this.httpClient.get('/users/check').subscribe({
          next: (data) => {
            return true;
          },
          error: () => {
            return false;
          },
        });
      }

内部canActivate警卫:

代码语言:javascript
复制
 canActivate(){
    return this.authService.isLoggedIn().subscribe(res => {
        if (!res) this.router.navigate(['login']);
        else return true;    
    });
 }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72877427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档