无法使用带有 MEAN 堆栈的 express-jwt 在服务器端验证令牌

Posted

技术标签:

【中文标题】无法使用带有 MEAN 堆栈的 express-jwt 在服务器端验证令牌【英文标题】:Unable to validate token on server side using express-jwt with MEAN stack 【发布时间】:2017-12-13 18:29:00 【问题描述】:

我正在尝试使用 express-jwt 保护我的 api。我正在使用 MEAN (Angular 4) 堆栈。我尝试了以下代码的许多变体,但无法弄清楚为什么我无法验证令牌。

下面列出的代码返回401 Unauthorized to the client。其他变体返回UnauthorizedError: Format is Authorization: Bearer [token]。有人看到下面的代码有什么问题吗?

服务器端代码

在我的 app.ts 文件中,我有以下内容:

  app.use('/api/volunteers/', jwt(
    secret: 'test',
    credentialsRequired: false,
    getToken: function fromHeaderOrQuerystring (req) 
      if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') 
        // console.log(req.headers.authorization.split(' ')[0] === 'Bearer')
        return req.headers.authorization.split(' ')[1];
       else if (req.query && req.query.token) 
        return req.query.token;
      
      return null;
    
  ));

问题:

    如果标头中的令牌有效,这是否设置 req.user? 我需要显式调用 getToken() 吗?

在我的 routes.ts 文件中,我有:

 app.get('/api/volunteers',
    function(req, res) 
    console.log('req user ' + req.user);
      // auth
      if (!req.user) 
        return   res.sendStatus(401);
      
      // logic
      Volunteer.find(, (err, docs) => 
        if (err) 
          res.status(400).send(err);
          return console.error(err);
        
        res.json(docs);
      );
    );

注意:在上面代码的第一行之后添加jwt(secret: 'test'),会返回UnauthorizedError: Format is Authorization: Bearer [token]

用户模型:

import * as bcrypt from 'bcryptjs';
import * as mongoose from 'mongoose';

const userSchema = new mongoose.Schema(
  username: String,
  email:  type: String, unique: true, lowercase: true, trim: true ,
  password: String,
  role: String
);

const User = mongoose.model('User', userSchema);

export default User;

用户处理程序:

import BaseHandler from './base';
import User from '../models/user';
import * as jwt from 'jsonwebtoken';
import * as dotenv from 'dotenv';
import 'zone.js';
import 'reflect-metadata';

export default class UserHandler extends BaseHandler 
  model = User;

  login = (req, res) => 
    this.model.findOne( email: req.body.email , (err, user) => 
      if (!user)  return res.sendStatus(403); 
      user.comparePassword(req.body.password, (error, isMatch) => 
        if (!isMatch)  return res.sendStatus(403); 
        // why sign with user
        // why do I need test
        const token = jwt.sign(user: user, 'test');
        res.status(200).json( token: token );
      );
    );
  ;

客户端代码

我服务的一部分:

  constructor(private http: Http) 
    this.headers = new Headers( 'Content-Type': 'application/json' );
    this.headers.append('authorization', localStorage.token);
    this.options = new RequestOptions( headers: this.headers );
  

  getVolunteers(): Observable<Volunteer[]> 
    return this.http.get('/api/volunteers', this.options)
      .map((res: Response) => res.json())
      .catch(handleError);
  

【问题讨论】:

如果标头中的令牌有效,是否设置 req.user? Ans: 需要用户自己设置 req.user UnauthorizedError: Format is Authorization: Bearer [token] 这个错误是因为app.ts中有下面这行 return req.headers.authorization.split(' ')[1];您必须返回整个令牌,包括“Bearer” 【参考方案1】:

在服务器端你可以这样做

var authentication = require('./auth');
router.route('/create')
    .all(authentication)
    .post(function(req, res)
        // Your Code
    );

并在 auth.js 中编写以下代码

var jwt = require('jwt-simple'),
    common = require('./common'),
    secretKey = require('./key');

module.exports = function (req, res, next) 
    var token = req.headers['authorization'];
    if (token) 
        try 
            var token = jwt.decode(token, secretKey);
            var user = token.user; // Get user from token in your way
            return next();
         catch (err) 
            // Throw error
        
     else 
       // Throw error
    
;

【讨论】:

谢谢!我最终使用了 jwt-simple 并遵循这个例子而不是 express-jwt

以上是关于无法使用带有 MEAN 堆栈的 express-jwt 在服务器端验证令牌的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 MEAN 堆栈连接到 Mongodb.atlas 集群

Express js 路由无法与 MEAN 堆栈按预期工作

Express-js 无法获取我的静态文件,为啥?

无法让 NODE_ENV 在开班时粘在我的 MEAN 堆栈上

Javascript + MEAN堆栈:如何在数组中正确找到“_id”字段(不是“id”)?

在MEAN堆栈应用程序中自定义JWT令牌的有效负载