0

我正在尝试学习如何保护基本的 Angular 应用程序。我正在使用带有 basicauth 的 springboot 后台。而且我已经实现了 HTTP_INTERCEPTOR。

我遵循了以下指南:

我的代码工作正常,但只有 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;
      });
    }

}
4

1 回答 1

0

您应该在刷新后将保存的信息保存在 localStorage 或 sessionStorage 或其他任何地方,以免出现任何问题。我的建议是在 app.component.ts 中执行此操作,例如下面的链接和示例代码。

我以前做过一次同样的事情。关联

// Restore user information from localStorage
const token = localStorage.getItem('token');
const user: User = JSON.parse(localStorage.getItem('user'));

if (token && user) {
  this._authService.setCurrentUser = user;
  this._authService.setUserLoggedIn = true;
} else {
  this._authService.logout();
  this._router.navigate(['/login']);
}

我希望这些信息可以帮助您解决问题。

于 2022-01-17T19:45:57.620 回答