簡體   English   中英

HTTP_INTERCEPTOR 僅與 angular 11 一起工作 1 次

[英]HTTP_INTERCEPTOR work only 1 times with angular 11

我正在嘗試學習如何保護基本的 angular 應用程序。 我正在使用帶有 basicauth 的 springboot 后台。 而且我已經實現了 HTTP_INTERCEPTOR。

我遵循了以下指南:

我的代碼工作正常,但只有 1 次。 只需調用表單登錄並執行它,重定向,一切都會出現在我的前台,狀態碼為 200。

但是,如果我點擊刷新按鈕,我的 API 回答狀態碼為 401。我在 HttpInterceptorService 的條件下添加了一條控制台日志消息,以測試用戶是否已連接並且此消息出現在控制台中,所以我認為它只是 header 沒有應用。

如果我導入了多個 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;
      });
    }

}

您應該在刷新后將保存的信息保存在 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']);
}

我希望這些信息可以幫助您解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM