我正在尝试学习如何保护基本的 Angular 应用程序。我正在使用带有 basicauth 的 springboot 后台。而且我已经实现了 HTTP_INTERCEPTOR。
我遵循了以下指南:
- https://www.baeldung.com/spring-boot-angular-web
- https://www.javaguides.net/2019/04/spring-boot-spring-security-angular-example-tutorial.html
我的代码工作正常,但只有 1 次。只需调用表单登录并执行它,重定向,一切都会出现在我的前台,状态码为 200。
但是,如果我点击刷新按钮,我的 API 会以状态码 401 回答。我在 HttpInterceptorService 的条件下添加了一条控制台日志消息,以测试用户是否已连接,并且此消息出现在控制台中,所以我认为它只是标题没有应用。
如果我导入了多个 HttpClientModule,我已经查过了,但我的 app.module.ts 中只有一个
这是一些代码:
应用模块
import { FormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { ProductServiceService } from './service/product-service.service';
import { HttpInterceptorServiceService } from './login/http-interceptor-service.service';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ProductListComponent } from './product-list/product-list.component';
import { LoginComponent } from './login/login.component';
import { ProductHomeComponent } from './product-home/product-home.component';
@NgModule({
declarations: [
AppComponent,
ProductListComponent,
LoginComponent,
ProductHomeComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
FormsModule
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HttpInterceptorServiceService,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
http-interceptor-service.service.ts
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
@Injectable()
export class HttpInterceptorServiceService implements HttpInterceptor {
constructor(private authService: AuthService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.authService.isUserLoggedIn() && req.url.indexOf('basicauth') === -1) {
console.log("User is logged");
const authReq = req.clone({
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': `Basic ${window.btoa(this.authService.username + ":" + this.authService.password)}`
})
});
return next.handle(authReq);
} else {
return next.handle(req);
}
}
}
auth.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class AuthService {
// BASE_PATH: 'http://localhost:8080'
USER_NAME_SESSION_ATTRIBUTE_NAME = 'authenticatedUser'
public username: String;
public password: String;
constructor(private http: HttpClient) {
}
authService(username: String, password: String) {
return this.http.get(`http://localhost:8080/basicauth`,
{ headers: { authorization: this.createBasicAuthToken(username, password) } }).pipe(map((res) => {
this.username = username;
this.password = password;
this.registerSuccessfulLogin(username, password);
}));
}
createBasicAuthToken(username: String, password: String) {
return 'Basic ' + window.btoa(username + ":" + password)
}
registerSuccessfulLogin(username, password) {
sessionStorage.setItem(this.USER_NAME_SESSION_ATTRIBUTE_NAME, username)
}
logout() {
sessionStorage.removeItem(this.USER_NAME_SESSION_ATTRIBUTE_NAME);
this.username = null;
this.password = null;
}
isUserLoggedIn() {
let user = sessionStorage.getItem(this.USER_NAME_SESSION_ATTRIBUTE_NAME)
if (user === null) return false
return true
}
getLoggedInUserName() {
let user = sessionStorage.getItem(this.USER_NAME_SESSION_ATTRIBUTE_NAME)
if (user === null) return ''
return user
}
}
登录组件.ts
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { AuthService } from './auth.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
username: string;
password : string;
errorMessage = 'Invalid Credentials';
successMessage: string;
invalidLogin = false;
loginSuccess = false;
constructor(
private route: ActivatedRoute,
private router: Router,
private authService: AuthService) { }
ngOnInit() {
}
handleLogin() {
this.authService.authService(this.username, this.password).subscribe((result)=> {
this.invalidLogin = false;
this.loginSuccess = true;
this.successMessage = 'Login Successful.';
this.router.navigate(['/products']);
}, () => {
this.invalidLogin = true;
this.loginSuccess = false;
});
}
}