简体   繁体   中英

Angular 8 loose data after refresh page

I have isAdmin boolean property which I am checking user logged in as user or admin. Backend is .net core 2.2, db - Postgre. Everything works fine but after refresh I lose isAdmin value. I have conditional show hide dropdown which is available only for admin roles. How don't lose data after refreshing? PS How to add logic also to my guard for isAdmin property? My component looks like:

 model: any = {};

  constructor(public authService: AuthService, private alertify: AlertifyService, private router: 
   Router) { }

  ngOnInit() {

  }


  login() {
    this.authService.login(this.model).subscribe(next => {
      this.model.isAdmin = true;
      this.alertify.success('Logged in as Admin')
    }, error => {
      this.alertify.error(error)
    }, () => {
      this.router.navigate(['/projects'])
    })
  }

  loginAsUser() {
    this.authService.loginAsUser(this.model).subscribe(next => {     
      this.model.isAdmin = false;
      this.alertify.success('Logged in as User')
    }, error => {
      this.alertify.error(error)
    }, () => {
      this.router.navigate(['/home'])
    })
  }

  loggedIn() {
    return this.authService.loggedIn();
  }

  logout() {
    localStorage.removeItem('token');
    this.alertify.message('logged out');
    this.router.navigate(['/home'])
  }

My html looks like:

<nav class="navbar navbar-expand-md navbar-light fixed-top bg-light">
  <div class="container">
    <a class="navbar-brand" [routerLink]="['/home']">
      <img [src]="iteraLogo" alt="Itera">
    </a>

    <div *ngIf="loggedIn()" class="dropdown" dropdown [hidden]="!model.isAdmin">
      <a class="dropdown-toggle" dropdownToggle>
        <strong class="text-primary">Admin Panel</strong>
      </a>
      <div class="dropdown-menu mt-4" *dropdownMenu>
        <ul class="navbar-nav">
          <li class="nav-item" routerLinkActive="router-link-active">
            <a class="nav-link" [routerLink]="['/projects']">Projects</a>
          </li>
          <li class="nav-item" routerLinkActive="router-link-active">
            <a class="nav-link" [routerLink]="['/hypervisors']">Hypervisors</a>
          </li>
          <li class="nav-item" routerLinkActive="router-link-active">
            <a class="nav-link" [routerLink]="['/management']">Management</a>
          </li>
          <li class="nav-item" routerLinkActive="router-link-active">
            <a class="nav-link" [routerLink]="['/users']">Users</a>
          </li>
          <li class="nav-item" routerLinkActive="router-link-active">
              <a class="nav-link" [routerLink]="['/user-projects']">Users Projects</a>
            </li>
        </ul>
      </div>
    </div>

    <ul class="navbar-nav mr-auto">
      <li class="nav-item" routerLinkActive="router-link-active">
        <a class="nav-link" [routerLink]="['/test']">About</a>
      </li>
    </ul>
    <div *ngIf="loggedIn()" class="dropdown" dropdown>
      <a class="dropdown-toggle" dropdownToggle>
        Welcome <strong>{{ authService.decodedToken?.unique_name | titlecase }}</strong>
      </a>
      <div class="dropdown-menu mt-3" *dropdownMenu>
        <a class="dropdown-item text-primary" [routerLink]="['/projects/', 
          authService.decodedToken?.nameid ]"><i class="fa fa-archive">&nbsp;My Projects</i></a>
        <div class="dropdown-divider"></div>
        <a class="dropdown-item text-danger" (click)="logout()"><i class="fa fa-sign- 
        out">&nbsp;Logout</i></a>
      </div>
    </div>

    <form *ngIf="!loggedIn()" #loginForm="ngForm" class="form-inline my-2 my-lg-0">
      <div class="input-group">
        <div class="input-group-prepend">
          <div class="input-group-text">
            <i class="fa fa-user-circle-o text-primary" aria-hidden="true"></i>
          </div>
        </div>
        <input class="form-control" placeholder="Username" name="username" required 
        [(ngModel)]="model.username" />
      </div>

      <div class="input-group">
        <div class="input-group-prepend">
          <div class="input-group-text">
            <i class="fa fa-unlock text-danger" aria-hidden="true"></i>
          </div>
        </div>
        <input class="form-control" placeholder="Password" name="password" required type="password"
          [(ngModel)]="model.password" />
      </div>
      <div>
        <button [disabled]="!loginForm.valid" type="submit" (click)="loginAsUser()" class="btn btn-primary my-2 my-sm-0">
          <i class="fa fa-user-circle" aria-hidden="true"></i>&nbsp;User
        </button>
        <button [disabled]="!loginForm.valid" type="submit" (click)="login()" class="btn btn-success 
           my-2 my-sm-0">
          <i class="fa fa-user-secret" aria-hidden="true"></i>&nbsp;Admin
        </button>
      </div>
    </form>

  </div>
</nav>

My guard looks like:

 canActivate(): boolean {
    if(this.authService.loggedIn()) {
      return true
    }    

    this.alertify.error('You have no access to see this page!!!');
    this.router.navigate(['/home']);
    return false;
  }

You will have to store your Auth_Token in localhost/indexDB/SessionStorage and then inside your route guard check if that token is valid or not.

This way your app will not require authentication until your token is valid .

Use this npm module to achieve this : enter link description here

When you refresh the page it does not persist variable values, you need to store either in local storage or cookie.

A simple way to solve this is to use this lib:

https://www.npmjs.com/package/ng2-cookies

To install this library, run:

npm install ng2-cookies

Component

import { Cookie } from 'ng2-cookies/ng2-cookies';

ngOnInit() {
    this.model.isAdmin = Cookie.get('isAdmin');
}

login() {
    this.authService.login(this.model).subscribe(next => {
      Cookie.set('isAdmin', 'true');
      this.alertify.success('Logged in as Admin')
    }, error => {
      this.alertify.error(error)
    }, () => {
      this.router.navigate(['/projects'])
    })
}

you can use ngx-cookie-service also

https://www.npmjs.com/package/ngx-cookie-service

You have to make the auth service API call with ngoninit of the components and get the isAdmin flag. That way when u refresh everytime ngOnInit will get involved and u ll get that flag.

ngOnInit(){   this.authService.login(this.model).subscribe(next => {
    this.model.isAdmin = true;
 });
}

Set a variable in localStorage upon successful login, like

isloggedIn(authUser) {
    return this.httpClient.post<any>(`${this.apiUrl}/api/users/login`, {user: authUser})
      .do(res => this.setSession(res.user))
      .shareReplay();
  }

  private setSession = (authResult) => {
    localStorage.setItem('TOKEN', authResult.token);
    localStorage.setItem('loggedUser', 'y');

    this._router.navigate(['dashboard'])
  };

Next time when you enter any component, check

if(!localStorage.getItem('loggedUser')){
      this._router.navigate(['login']);
      return false;
    }
    return true;

this will authenticate user without calling API again. just get key from LocalStorage.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM