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
相关产品推荐
相关产品推荐

