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

Angular页面加载时如何管理生成的Bearer Token并用于请求

解决方案

1. 改造LoginService存储并管理Token

首先修改login.service.ts,添加Token的存储、获取逻辑,同时在登录成功后保存Token:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, tap } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LoginService {
  url = 'http://localhost:3030/api/auth/login';
  // 用BehaviorSubject管理Token状态,支持订阅更新
  private tokenSubject = new BehaviorSubject<string | null>(null);
  public token$ = this.tokenSubject.asObservable();

  constructor(private http: HttpClient) { 
    // 页面刷新时从localStorage恢复已保存的Token
    const savedToken = localStorage.getItem('authToken');
    if (savedToken) {
      this.tokenSubject.next(savedToken);
    }
  }

  loginServer(){
    return this.http.post<{ token: string }>(this.url, {"username": "testadmin", "password": "123456"}).pipe(
      tap(response => {
        const token = response.token;
        // 保存Token到localStorage实现持久化
        localStorage.setItem('authToken', token);
        // 更新Token状态
        this.tokenSubject.next(token);
      })
    );
  }

  // 获取当前Token
  getToken(): string | null {
    return localStorage.getItem('authToken') || this.tokenSubject.value;
  }
}

2. 创建HTTP拦截器自动添加请求头

创建auth.interceptor.ts,拦截所有HTTP请求,自动带上Bearer Token:

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

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor(private loginService: LoginService) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const token = this.loginService.getToken();
    if (token) {
      // 克隆请求并添加Authorization头(请求是不可变的,必须克隆修改)
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
    }
    return next.handle(request);
  }
}

3. 注册拦截器到应用模块

在app.module.ts中注册拦截器,让其生效:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './auth.interceptor';
// 其他组件/模块导入

@NgModule({
  declarations: [
    // 声明你的组件
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true // 允许多个拦截器共存
    }
  ],
  bootstrap: [/* 你的根组件 */]
})
export class AppModule { }

4. 页面加载时自动登录(或恢复登录状态)

在CategoriesComponent中,页面初始化时判断是否已有Token,无Token则触发登录,后续请求会自动带上Token:

import { Component, OnInit } from '@angular/core';
import { CategoryService } from './category.service';
import { LoginService } from './login.service';

@Component({
  // 组件元数据
})
export class CategoriesComponent implements OnInit {
 
  constructor(private categoryService: CategoryService, private loginService: LoginService) { }
  
  ngOnInit(): void {
    const token = this.loginService.getToken();
    if (!token) {
      // 无Token时触发登录
      this.loginService.loginServer().subscribe(
        () => {
          console.log('登录成功,Token已保存');
          // 这里可以调用需要权限的接口,比如 this.categoryService.getCategories()
        },
        error => {
          console.error('登录失败', error);
        }
      );
    } else {
      // 已有Token,直接执行需要权限的操作
      console.log('已存在Token,直接使用');
      // this.categoryService.getCategories().subscribe(...);
    }
  }
}

说明

  • 用localStorage存储Token可实现页面刷新后保持登录状态;
  • HTTP拦截器会自动给所有请求添加Authorization头,无需手动在每个接口里设置;
  • 若需更安全的存储,可改用sessionStorage或专门的本地存储库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 23:18:42