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

时间:2017-07-10 06:20:16

标签: angular jwt mean-stack express-jwt

我正在尝试使用express-jwt保护我的apis。我正在使用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;
    }
  }));

问题:

  1. 如果标题中的标记有效,是否设置req.user?
  2. 我是否需要明确调用getToken()?
  3. 在我的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);
      }
    

1 个答案:

答案 0 :(得分: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
    }
};