【问题标题】:angular2-jwt token alwas not validangular2-jwt 令牌一直无效
【发布时间】:2017-03-08 15:45:55
【问题描述】:

所以我有一个简单的 Angular 2/laravel 应用程序,它支持 jwt 身份验证。我有一个服务,每次调用路由时都会使用 angular2-jwt tokenNotExpired() 函数验证 jwt 令牌是否有效,但此函数总是出于某种原因返回 false,因此用户将始终被重定向到登录页面。

因此,就像用户登录一样,将从后端生成一个令牌并保存在本地存储中,然后服务将在使用 CanActivate 生命周期挂钩启动任何路由之前检查令牌是否有效。

这是我到目前为止所做的:

登录组件:

   ...
            this.http.post(SERVER_URL + 'auth', body, {
                headers: headers
            }
            ).subscribe(
                data => {

                    localStorage.setItem('auth_token', data.json().token);
                    this.authHttp.get(SERVER_URL + 'auth/user', headers)
                        .subscribe(
                        data => {
                            this.store.dispatch({ type: SET_CURRENT_USER_PROFILE, payload: data.json().user });
                            localStorage.setItem('user', data.json().user);
                            this.router.navigate(['/home']);

                        },
                        err => console.log('Fehlermeldung: ' + err)
                        );

                },
...

应用程序模块:

...
 { provide: AuthConfig, useValue: new AuthConfig({
              headerName: 'Authorization',
              headerPrefix: 'Bearer ',
              tokenName: 'auth_token',
              tokenGetter: (() => localStorage.getItem('auth_token')),
              globalHeaders: [{ 'Content-Type': 'application/json' }],
              noJwtError: true,
              noTokenScheme: true
  })},
    AuthHttp
...

auth.service: // 检查 JWT 令牌服务

import { tokenNotExpired } from 'angular2-jwt';
import { Injectable } from '@angular/core';

@Injectable()
export class AuthService  {

    loggedIn() {
    return tokenNotExpired();
    }

}

auth.guard.service:

// Check if the Token of the user is still valid
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
import { AppState } from '../shared/interfaces';
import { SET_CURRENT_USER_PROFILE } from '../shared/state.actions';



import { Store } from '@ngrx/store'

@Injectable()
export class AuthGuardService implements CanActivate {

  constructor(private auth: AuthService, private router: Router, private store: Store<AppState>) {}

  canActivate() {
    if(this.auth.loggedIn()) {
      return true;
    } else {
        console.log ('Token expired or not valid')
        localStorage.setItem('auth_token', '');
        localStorage.setItem('user', '');
        this.store.dispatch({ type: SET_CURRENT_USER_PROFILE, payload: null });
        this.router.navigate(['/']);
      return false;
    }
  }
}

应用程序路由:

const routes: Routes = [
  { path: 'home', component: HomeComponent},
  { path: 'about', component: AboutComponent, canActivate: [AuthGuardService]},
  { path: 'profile/:id', component: ProfileComponent, canActivate: [AuthGuardService]},
  { path: '', component: LoginComponent}
];

编辑:从后端来看,一切正常,因为令牌是在用户登录后生成并存储在本地存储中的。

【问题讨论】:

    标签: angular jwt


    【解决方案1】:

    解决方案:所以这就是我为可能遇到相同问题的每个人修复它的方法,我使用了 JWTHelper 函数 isTokenExpired() 而不是 tokenNotExpired,我颠倒了服务中的逻辑,但它的工作原理并不确定为什么

    auth.service 现在看起来像这样:

    @Injectable()
    export class AuthService  {
    
        private jwtHelper: JwtHelper = new JwtHelper();
        private token = localStorage.getItem('auth_token');
    
        isExpired() {
            return this.jwtHelper.isTokenExpired(this.token);
        }
    
    }
    

    和 auth.guard.service 可以激活():

      canActivate() {
        if (this.auth.isExpired()) {
            console.log (this.auth.isExpired());
            localStorage.setItem('auth_token', '');
            localStorage.setItem('user', '');
            this.store.dispatch({ type: SET_CURRENT_USER_PROFILE, payload: null });
            this.router.navigate(['/']);
          return false;
        } else {
          return true;
        }
      }
    

    【讨论】:

      【解决方案2】:

      由于属性名称,它假定它是“令牌”。因此,当您提供属性名称作为第一个参数时,它将正常工作。

      例如:

      tokenNotExpired('auth_token')

      可以在此处找到有关此问题的更多信息: https://github.com/auth0/angular2-jwt/issues/334

      【讨论】:

        【解决方案3】:
        `localStorage.setI`tem('id-token',token);
        

        用于将令牌保存到本地存储/会话存储的相同令牌名称 可以作为参数传递给

        return tokenNotExpired('id-token');
        

        【讨论】:

          【解决方案4】:

          将令牌作为参数传递。

          改变

          loggedIn() {
            return tokenNotExpired();
          }
          

          loggedIn() {
            return tokenNotExpired('id_token');
          }
          

          【讨论】:

          • 解释一下为什么会这样,以及 OP 如何自己解决这个问题会很有帮助。
          • 用户成功登录后,将用户的 ID 令牌发送到您的服务器以提高安全性。然后,在服务器上,验证 ID 令牌的完整性,并使用令牌中包含的用户信息来建立会话或创建新帐户。
          • ITYM 'auth_token'
          • 是的,我们可以将 auth_token 设置为 authToken = localStorage.getItem('id_token');
          猜你喜欢
          • 2021-04-13
          • 2021-09-25
          • 2019-03-19
          • 2018-07-14
          • 2020-04-19
          • 2016-10-20
          • 2018-04-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多