【问题标题】:Angular 8 loose data after refresh page刷新页面后Angular 8松散数据
【发布时间】:2019-11-28 18:22:36
【问题描述】:

我有 isAdmin 布尔属性,我正在检查以用户或管理员身份登录的用户。 后端是 .net core 2.2,db - Postgre。 一切正常,但刷新后我失去了 isAdmin 值。 我有条件显示隐藏下拉菜单,仅适用于管理员角色。 刷新后如何不丢失数据? 附言如何为我的 isAdmin 属性添加逻辑? 我的组件看起来像:

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

我的 html 看起来像:

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

我的后卫看起来像:

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

【问题讨论】:

  • 您可能需要将其保存在 LocalStorage 中,否则数据将始终丢失。不是 Angular,任何其他库都将数据永久存储在变量中。您需要 cookie 或 LocalStorage 来保存数据

标签: javascript html angular typescript


【解决方案1】:

当您刷新页面时,它不会保留变量值,您需要存储在本地存储或 cookie 中。

解决这个问题的一个简单方法是使用这个库:

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

要安装这个库,运行:

npm install ng2-cookies

组件

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

你也可以使用 ngx-cookie-service

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

【讨论】:

    【解决方案2】:

    您必须将 Auth_Token 存储在 localhost/indexDB/SessionStorage 中,然后在路由保护中检查该令牌是否有效。

    这样,您的应用在令牌有效之前不需要身份验证

    使用这个 npm 模块来实现这个:enter link description here

    【讨论】:

    • 我为后端和前端设置了所有 jwt,它工作正常。我将我的 jwt 存储在 localStorage 中。但我失去的不是 jwt 令牌,而是 isAdmin 布尔值。我的问题是如何在刷新后不松开 isAdmin。所以 jwt 没有问题,因为它即使在刷新后也能工作
    • 您必须在 AuthGuard CanActivate 方法中添加此登录。检查存储中存在的令牌是否有效然后返回 true 否则返回 false 并导航到登录屏幕
    【解决方案3】:

    您必须使用组件的 ngoninit 进行身份验证服务 API 调用并获取 isAdmin 标志。这样,当你每次刷新时,ngOnInit 都会参与进来,你会得到那个标志。

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

    【讨论】:

    • 当我将代码放入 ngOnInit 时,我收到了来自拦截器的异常 --- 对象引用未设置为对象的实例。
    • 好的.. 我现在明白你的问题了。您分别有两个用户登录,并且您已经将令牌存储在本地存储中,这很容易。您可以在令牌内的服务本身中设置此管理标志并解码令牌以获取值。
    【解决方案4】:

    登录成功后在localStorage中设置一个变量,比如

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

    下次输入任何组件时,检查

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

    这将验证用户而无需再次调用 API。只需从 LocalStorage 获取密钥。

    【讨论】:

      猜你喜欢
      • 2019-05-15
      • 1970-01-01
      • 1970-01-01
      • 2019-02-11
      • 1970-01-01
      • 2017-03-05
      • 1970-01-01
      • 1970-01-01
      • 2017-11-22
      相关资源
      最近更新 更多