You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular2/4/5基于令牌认证安全调用WebAPI接口的实现

Solution: Securely Call Web API with JWT Token in Angular

Hey there! Let's get your token-based authentication working properly for your Web API calls. Here's how to integrate the token into your service calls and make the implementation cleaner and more secure:

Step 1: Refactor UserService to Add Token to Request Headers

First, let's create a reusable method to build authentication headers, then update your API methods to use this header. This avoids repeating code across all authenticated endpoints.

Here's the updated 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 {
  constructor(private http: HttpClient, private uihelper: UIHelperClass) {}

  // Private method to get authenticated headers
  private getAuthHeaders(): HttpHeaders {
    const userToken = localStorage.getItem('userToken');
    let headers = new HttpHeaders();
    
    // Add Bearer token if available
    if (userToken) {
      headers = headers.set('Authorization', `Bearer ${userToken}`);
    }
    
    return headers;
  }

  UserForm(person: Person){
    const body: Person = {
      FirstName: person.FirstName,
      LastName: person.LastName
    };
    
    // Use our authenticated headers for this secured endpoint
    return this.http.post(
      this.uihelper.CallWebAPIUrl("/api/User/AddUser"), 
      body,
      { headers: this.getAuthHeaders() }
    );        
  }

  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' // Keep this since login doesn't require prior auth
    });
    return this.http.post(this.uihelper.CallWebAPIUrl("/token"), data, { headers: reqHeader });           
  }

  getUserClaims(){
    // Add auth headers to this secured request too
    return this.http.get(
      this.uihelper.CallWebAPIUrl("/api/GetUserClaims"),
      { headers: this.getAuthHeaders() }
    );
  }
}

Key Changes Explained:

  • Reusable getAuthHeaders() Method: This method checks for a stored token and builds the Authorization header with the standard Bearer scheme. Every authenticated request uses this consistent logic, so you don't have to duplicate code.
  • Updated UserForm and getUserClaims: These methods now use authenticated headers instead of the No-Auth header, since those endpoints require a valid token to access.
  • Preserved userAuthentication: The login endpoint keeps the No-Auth header as intended—you don't have a token yet when logging in, so this request should bypass auth checks.

Step 2: Clean Up Home Component's OnSubmit Method

In your home.ts, the line localStorage.getItem('userToken'); doesn't actually do anything right now. Since we're handling token injection in the service, you can remove it. Here's the cleaned-up method:

OnSubmit(form: NgForm) {
  this.userService.UserForm(form.value)
    .subscribe((data: any) => {
      if (data.Succeeded == true) {
        console.log("Form submitted successfully!");
        // Add your success logic here (e.g., reset the form, show a toast notification)
      }
    }, (err) => {
      // Don't forget to handle errors like expired tokens or invalid requests
      console.error("Error submitting form:", err);
    });      
}

Bonus: Use Angular HttpInterceptor for Global Token Injection

For a more scalable solution, consider using an HttpInterceptor to automatically add the token to every outgoing request. This means you don't have to call getAuthHeaders() in every service method.

Here's a quick implementation example:

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // Skip adding token for requests marked as No-Auth (like login)
    if (request.headers.get('No-Auth') === 'True') {
      return next.handle(request);
    }

    const userToken = localStorage.getItem('userToken');
    if (userToken) {
      // Clone the request and inject the Authorization header
      const clonedRequest = request.clone({
        headers: request.headers.set('Authorization', `Bearer ${userToken}`)
      });
      return next.handle(clonedRequest);
    }

    return next.handle(request);
  }
}

Then register the interceptor in your app.module.ts:

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './auth.interceptor';

@NgModule({
  ...
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true
    }
  ],
  ...
})
export class AppModule { }

With this interceptor, all requests automatically get the token added unless you explicitly mark them with No-Auth: True.

Quick Security Notes

  • Token Storage: localStorage is common for SPAs, but it's vulnerable to XSS attacks. If your app handles sensitive data, consider using HttpOnly cookies (this requires backend changes to support cookie-based auth).
  • Token Expiry: Add logic to handle expired tokens (e.g., redirect to login when you get a 401 Unauthorized response).
  • HTTPS: Always use HTTPS in production to prevent token interception.

内容的提问来源于stack exchange,提问作者Shailesh Bhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:19:43