【问题标题】:Angular and JWT roles disappearance when refresh page刷新页面时 Angular 和 JWT 角色消失
【发布时间】:2019-03-18 03:31:53
【问题描述】:

我正在编写带有身份验证部分的 CRUD 应用程序,因此我使用 JWT 角色管理页面之间的方向,因此当用户登录到应用程序时,他只会在菜单中看到与其角色相关的链接。

AuthenticationService.ts

import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {JwtHelper} from 'angular2-jwt';

@Injectable()
export class AuthenticationService {

  private host:string="http://localhost:8080";
  private jwtToken:string=null;
  private roles:Array<any>=[];
  private tk:any;

  constructor(private http:HttpClient){

  }
  login(user){
    return this.http.post(this.host+"/login",user, {observe:'response'});
  }

  logout(){
    this.jwtToken=null;
    localStorage.removeItem('token');
  }

  saveToken(jwt:string){
    this.jwtToken=jwt;
    localStorage.setItem('token',jwt);
    let jwtHelper=new JwtHelper();
    this.roles=jwtHelper.decodeToken(this.jwtToken).roles;
  }

  loadToken(){
    return this.jwtToken=localStorage.getItem('token');
  }

  isAdmin(){
    for(let r of this.roles) {
      console.log("********************************"+r);
      if(r.authority=='ADMIN') return true;
    }
    return false;
  }
  isDeveloper(){
    for(let r of this.roles) {
      console.log("********************************"+r);
      if(r.authority=='DEVELOPER') return true;
    }
    return false;
  }
  isCommercial(){
    for(let r of this.roles) {
      console.log("********************************"+r);
      if(r.authority=='COMMERCIAL') return true;
    }
    return false;
  }

  isOnline(){
    this.jwtToken=localStorage.getItem('token');
    if (this.jwtToken != null) return true;
    return false;
  }
  isOffline(){
    this.jwtToken=localStorage.getItem('token');
    if (this.jwtToken == null) return true;
    return false;
  }

}

app.component.html

 <!-- partial -->
  <div [ngClass]="{'container-fluid page-body-wrapper':authenticationService.isOnline()}">
    <!-- partial:partials/_sidebar.html -->
    <nav *ngIf="authenticationService.isOnline()" class="sidebar sidebar-offcanvas" id="sidebar">
      <ul class="nav">
        <li class="nav-item nav-profile">
          <a href="#" class="nav-link">
            <div class="nav-profile-image">
              <img src="assets/images/faces/face1.jpg" alt="profile">
              <span class="login-status online"></span> <!--change to offline or busy as needed-->
            </div>
            <div class="nav-profile-text d-flex flex-column">
              <span class="font-weight-bold mb-2">David Grey. H</span>
              <span class="text-secondary text-small">Project Manager</span>
            </div>
            <i class="mdi mdi-bookmark-check text-success nav-profile-badge"></i>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link" routerLink="/tasks">
            <span class="menu-title">Dashboard</span>
            <i class="mdi mdi-home menu-icon"></i>
          </a>
        </li>
        <li *ngIf="authenticationService.isAdmin()" class="nav-item">
          <div class="dropdown">
            <a class="nav-link" data-toggle="collapse" (click)="OnClik3()" data-target="#myNavbar3">
              <span class="menu-title">Admin Area</span>
              <i class="menu-arrow"></i>
              <i class="mdi mdi-worker"></i>
            </a>
            <div class="collapse navbar-collapse" [ngClass]="{'show': buttontoggled3}" id="myNavbar3">
              <ul class="nav flex-column sub-menu">
                <li class="nav-item">
                  <a class="nav-link" data-toggle="dropdown" routerLink="/roles">Roles</a>
                </li>
                <li class="nav-item">
                  <a class="nav-link" data-toggle="dropdown" routerLink="/users">Users</a>
                </li>
                <li class="nav-item">
                  <a class="nav-link" data-toggle="dropdown" href="#">XXX API</a>
                </li>
              </ul>
            </div>
          </div>
        </li>
        <li *ngIf="authenticationService.isAdmin() || authenticationService.isCommercial()" class="nav-item">
        <div class="dropdown">
          <a class="nav-link" data-toggle="collapse" (click)="OnClik1()" data-target="#myNavbar1">
            <span class="menu-title">Network</span>
            <i class="menu-arrow"></i>
            <i class="mdi mdi-google-circles-extended"></i>
          </a>
          <div class="collapse navbar-collapse " [ngClass]="{'show': buttontoggled1}" id="myNavbar1">
            <ul class="nav flex-column sub-menu">
              <li class="nav-item">
                <a class="nav-link" data-toggle="dropdown" routerLink="/companies">Companies</a>
              </li>
              <li class="nav-item">
              <a class="nav-link" data-toggle="dropdown" routerLink="/contacts">Contacts</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" data-toggle="dropdown" href="#">Whatsapp API</a>
              </li>
            </ul>
          </div>
        </div>
        </li>

问题是当用户登录时菜单很好,但是当他刷新页面或单击上一页或下一页时,菜单中具有上述条件的链接消失但用户仍然登录。 我怎么解决这个问题?请问有什么建议吗?

【问题讨论】:

  • 看起来当您加载令牌时,您也需要加载角色(就像您在 saveToken 中所做的那样)
  • @user184994 谢谢!

标签: angular typescript jwt


【解决方案1】:

like @user184994 说我需要像这样加载角色:

isAdmin(){
    let jwtHelper=new JwtHelper();
    this.roles=jwtHelper.decodeToken(this.jwtToken).roles;
    for(let r of this.roles) {
      console.log("********************************"+r);
      if(r.authority=='ADMIN') return true;
    }
    return false;
  }

【讨论】:

  • 最好只在loadToken函数内执行一次this.roles=jwtHelper.decodeToken(this.jwtToken).roles;,否则每次你想检查他们是否是管理员时都会解码令牌,这是不必要的开销
猜你喜欢
  • 2017-11-04
  • 1970-01-01
  • 2017-11-22
  • 2013-07-16
  • 2012-09-21
  • 2020-11-19
  • 1970-01-01
  • 2020-08-28
  • 1970-01-01
相关资源
最近更新 更多