HTTP_INTERCEPTOR work only 1 times with angular 11

271 Views Asked by At

I'm trying to learn how to secure a basic angular app. I'm working with springboot back office with basicauth. And I've implemented HTTP_INTERCEPTOR.

I've followed this guides:

My code works fine but only 1 time. Just call the form login and perform it, redirect and everything appears in my front office with status code 200.

But if i hit the refresh button, my API answer with status code 401. I've added a console log message in my condition in HttpInterceptorService to test if user are connected and this one appear in console so i think it's just header who are not applied.

I've looked up if i've import multiple HttpClientModule, but only one in my app.module.ts

Here's some code:

AppModule

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
  }
}

login.component.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;
      });
    }

}
1

There are 1 best solutions below

0
On

You should save the information you have saved in the localStorage or sessionStorage or anywhere else after refreshing it so that you do not have any problems. My suggestion is to do this in the app.component.ts , such as the link and sample code below.

I have done the same thing once before. link

// 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']);
}

I hope this information helps you solve your problem.