【问题标题】:Angular and Node: JWT authentication when accessing directly with a URL to a secret routeAngular 和 Node:直接使用 URL 访问秘密路由时的 JWT 身份验证
【发布时间】:2018-10-22 20:53:54
【问题描述】:

在我的项目中,我使用 Angular 5、nodejs、JWT 来签署令牌,并使用 passport.js 来管理身份验证(令牌解码)。在后端,当我使用 Angular 拦截器时,身份验证工作得很好,它会在拦截 http 请求时自动设置标头。

假设我正在访问 /user/profile,这是我在节点中的受保护路由,如果我直接在浏览器中键入受保护路由(完整 url http://localhost:3000/user/profile),我如何才能设法授予已通过身份验证的用户访问该页面,而不是来自 passport.js 的未经授权的消息,当然在标头中看不到任何令牌(正文,查询都不)?

我管理它的唯一方法是创建这条路线:

router.get('/isauthenticated', passport.authenticate('jwt', {session: false}), function (req, res) {
res.json({
    id: req.user.id,
    email: req.user.email
});
});

并在 ProfileComponent 的“ngOnInit”中调用它。如果 /isauthenticated 顺利,那么我让用户访问个人资料页面。 我认为这个解决方案是一种解决方法,绝对不优雅......所以我的问题是,除了使用或不使用passport.js:

是否可以在 Angular 中使用 JWT 身份验证并使用 nodejs 保护路由,然后让已经通过身份验证的用户(当然,它有一个未过期的令牌)进入受保护的路由,即使他直接在浏览器中输入网址?

请告诉我,即使您使用其他东西而不是 passport.js,或者我是否必须使用其他策略。

【问题讨论】:

    标签: node.js angular authentication jwt passport.js


    【解决方案1】:

    您可以将 jwt 令牌存储在浏览器的本地存储中。然后,您可以使用名为“tokenNotExpired()”的方法检查该令牌是否已过期。 身份验证服务应该像这样改变。

    import { Injectable } from '@angular/core';
    import { Http, Headers } from '@angular/http';
    import 'rxjs/add/operator/map';
    import { tokenNotExpired } from 'angular2-jwt';
    import { NgModule} from '@angular/core';
    
    
    @Injectable()
    export class AuthService {
      authToken: any;
      user: any;
    
      constructor(private http:Http) { }
    
      registerUser(user){
        let headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this.http.post('https://herokuapp.com/users/register', user,{headers: headers})
          .map(res => res.json());
      }
    
      authenticateUser(user){
        let headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this.http.post('https://herokuapp.com/users/authenticate', user,{headers: headers})
          .map(res => res.json());
      }
    
      getProfile(){
        let headers = new Headers();
        this.loadToken();
        headers.append('Authorization', this.authToken);
        headers.append('Content-Type', 'application/json');
        return this.http.get('https://herokuapp.com/users/profile',{headers: headers})
          .map(res => res.json());
      }
    
      storeUserData(token, user){
        localStorage.setItem('id_token', token);
        localStorage.setItem('user', JSON.stringify(user));
        this.authToken = token;
        this.user = user;
      }
    
      loadToken(){
        const token = localStorage.getItem('id_token');
        this.authToken = token;
      }
    
      loadUser(){
        const user = localStorage.getItem('user');
      }
    
      loggedIn() {
        return tokenNotExpired();  //Expired => return false
      }
    
      logout(){
        this.authToken = null;
        this.user = null;
        localStorage.clear();
      }
    }

    login.component.ts 应该这样改

    onLoginSubmit() {
        const user = {
          email: this.email,
          password: this.password
        }
        
         
        this.authService.authenticateUser(user).subscribe(data => {
          if (data.success) {
            this.authService.storeUserData(data.token, data.user);
            this.router.navigate(['/pages/dashboard']);
          } else {
            swal(
              'Oops...',
              'Invalid Email or Password..!',
              'error'
            )
            this.router.navigate(['/login']);
            this.password = '';
          }
        });
    }

    然后您可以将此 ngOnInit() 方法添加到任何 component.ts 文件中。如果令牌存储在本地存储中,那么您可以毫无问题地转到该页面。您也可以通过输入这样的 url 转到任何页面。 (http://localhost:3000/user/profile)

    ngOnInit() {
        this.authService.loadToken();
        if(!localStorage.getItem('id_token')){
          this.router.navigate(['/login']);  
        }
    }

    【讨论】:

      猜你喜欢
      • 2018-09-03
      • 1970-01-01
      • 2020-07-23
      • 2021-12-16
      • 2016-12-27
      • 1970-01-01
      • 2016-09-25
      • 2016-01-10
      • 2017-11-25
      相关资源
      最近更新 更多