在 Angular2/4/5 中,如何基于基于令牌的身份验证安全地调用 WebAPI 操作

Posted

技术标签:

【中文标题】在 Angular2/4/5 中,如何基于基于令牌的身份验证安全地调用 WebAPI 操作【英文标题】:In Angular2/4/5, How to Securely call WebAPI action, based on Token based Authentication 【发布时间】:2018-08-25 07:10:47 【问题描述】:

我需要知道,在 Angular FrontEnd 中获取令牌后,如何安全地调用 WebAPI 操作方法。下面是我的登录组件代码,在发送用户名和密码后,我将 usertoken 设置为 localstorage。然后我导航到主页。此处使用的所有代码均基于this video tutorial。也有轻微的修改,因为我也在 html 中使用 Ionic 代码

login.ts

constructor(private userService : UserService, public navCtrl: NavController)   
OnSubmit(userName,password)
         this.userService.userAuthentication(userName,password).subscribe((data : any)=>
          localStorage.setItem('userToken',data.access_token);
          //this.router.navigate(['/home']);
          this.navCtrl.push(HomeComponent);
        ,
        (err : HttpErrorResponse)=>
          this.isLoginError = true;
        );
      

在下面显示的代码中,我根据上面给定的用户名和密码获取用户详细信息。请关注下面组件的 OnSubmit() 方法。 这是基于 usertoken 提交另一种形式的 Home 组件的方法/事件,我需要您的帮助

home.ts

constructor(public navCtrl: NavController, private userService: UserService)      
ngOnInit() 
    this.resetForm();
    this.userService.getUserClaims().subscribe((data: any) => 
    this.userClaims = data;    
    );        
  
OnSubmit(form: NgForm) 
this.userService.UserForm(form.value)
  .subscribe((data: any) => 
    localStorage.getItem('userToken');

    if (data.Succeeded == true) 
     // this.resetForm(form);
     return "hello";
    

  );      

请关注以下服务的UserForm方法,我需要您的帮助。

user.service.ts

import  Injectable  from '@angular/core';
import  HttpClient, HttpHeaders  from '@angular/common/http';
import  UIHelperClass  from '../UIHelperClasses/UIHelperClass';
import  Person  from './person.model'; 

@Injectable()
export class UserService 
UserForm(person:Person)
    const body: Person = 
      FirstName: person.FirstName,
      LastName: person.LastName
    
       //var reqHeader = new HttpHeaders('No-Auth':'True');
    var reqHeader = new HttpHeaders('No-Auth':'False');
       //return this.http.post(this.rootUrl + '/api/User/Register', body,headers : reqHeader);
    return this.http.post(this.uihelper.CallWebAPIUrl("/api/User/AddUser"), body,headers : reqHeader);        
  

  userAuthentication(userName, password) 
    var data = "username=" + userName + "&password=" + password + "&grant_type=password";
    var reqHeader = new HttpHeaders( 'Content-Type': 'application/x-www-urlencoded','No-Auth':'True' );
        //return this.http.post(this.rootUrl + '/token', data,  headers: reqHeader );
    return this.http.post(this.uihelper.CallWebAPIUrl("/token"), data,  headers: reqHeader );           
  

  getUserClaims()
       //return  this.http.get(this.rootUrl+'/api/GetUserClaims');
   return  this.http.get(this.uihelper.CallWebAPIUrl("/api/GetUserClaims"));

  

如何使用,上面的UserForm服务方法中的代码类型如下。我需要保护我的请求/WebAPI(基于此令牌,我需要调用 Web API。它可能是 GetPost 请求)。我已将this tutorial 的 EmpService.js 引用为以下代码

user.service.ts

xxx=localStorage.getItem('userToken');
  authHeaders: any[] = [];
  if (xxx) 
    this.authHeaders.Authorization = 'Bearer ' + xxx;

【问题讨论】:

【参考方案1】:

您可以使用angular2-jwt,它在angular 5 和httpClient 中完美运行,在提供令牌来源(localStorage 或redux 存储)后,令牌将自动添加到所有Http 请求中:

export function tokenGetter() 
  return localStorage.getItem('access_token');


@NgModule(
  bootstrap: [AppComponent],
  imports: [
  HttpClientModule,
  JwtModule.forRoot(
   config: 
     tokenGetter: tokenGetter,
     whitelistedDomains: ['localhost:3001'] // token will be sent to these domains only 
   
 )
 ]
)

例如,您可以添加一个 http 拦截器以在登录调用的情况下删除令牌

【讨论】:

以上是关于在 Angular2/4/5 中,如何基于基于令牌的身份验证安全地调用 WebAPI 操作的主要内容,如果未能解决你的问题,请参考以下文章

在 HTTP 连接中使用基于令牌的身份验证时如何防止重放攻击

如何基于此 curl 设置授权令牌?

如何在 Java 中基于 SAS 令牌访问 Azure WASB 容器?

如何使用基于策略的授权将所需的声明附加到令牌?

如何使用 MVC 5 在基于令牌的身份验证中检查用户是不是从控制器登录?

如何在微服务中添加基于 Jwt 令牌的安全性