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

Unable to validate token on server side using express-jwt with MEAN stack

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

下面列出的代码 return 是 401 Unauthorized to the client。其他变体 return 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;
    }
  }));

问题:

  1. 如果 header 中的令牌有效,是否设置 req.user?
  2. 我需要显式调用 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);
      });
    });

注意:在 returns UnauthorizedError: Format is Authorization: Bearer [token].

正上方代码的第一行后添加 jwt({secret: 'test'}),

用户模型:

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

在服务器端你可以这样做

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