使用passport和typescript进行Node.js身份验证:找不到req.user

时间:2017-05-15 18:29:37

标签: node.js express passport.js

我目前正在使用typescript,WebStorm,passport和jwt为node.js微服务应用程序开发身份验证服务。在尝试将路由添加到“/ api / login”时,我注意到intellisense似乎没有获取req.user的用户对象或req.header.authorization的授权对象。例如,以下方法无效,因为它找不到用户对象:

private generateToken(req: Request, res: Response, next: NextFunction){
req.token = jwt.sign({
  id: req.user.id,
  firstname: req.user.firstname,
  lastname: req.user.lastname,
  roles: req.user.roles
}, process.env.AUTH_KEY, {
  expiresIn: "7d"
});
return next();
}

我正在使用来自express的Request对象:

import { NextFunction, Request, Response, Router } from "express";

我是否需要使用其他Request对象?

另外,如果我需要强制对某些api路由进行身份验证但是还要锁定其他路由,那么应该如何使用passport-jwt来完成?我知道有一个express-unless包可以用于express-jwt。

1 个答案:

答案 0 :(得分:3)

不确定为什么这个问题被低估了,可能是因为它应该是两个单独的问题。

您可以扩展Express的类型声明。

扩展快递类型定义

使用此文件将文件library-ext.d.ts添加到源目录中。

declare module 'express' {
  export interface Request {
        user?: any;
    }
}

req.header.authorization尝试:req.headers ['授权']。请注意''。

与一般身份验证相关

这取决于您的注册用户是否也可以使用guest路由。如果您在访客路由上永远不需要身份,那么只需在经过身份验证的路由上注册护照身份验证中间件,或者将路由拆分为单独的路由器。这很简单,只需搜索堆栈溢出或查看文档即可。

更复杂的情况是,当您需要经过身份验证和未经身份验证的用户访问路由时 - 请考虑访客或经过身份验证的客户向购物车添加内容。不幸的是,当一个令牌不在授权标题中时,passport-jwt拒绝使用401,所以我找到的最简单的方法是使用中间件来添加已知值来代表一个令牌,而不是分支项目或滚动我自己的策略。否则匿名请求。然后确保中间件在受影响路由中的护照身份验证之前。这是一个让你前进的片段:

<强> CoreCtrl

class CoreCtrl {

  simulateAnonymous(req, res, next) {
    if (!req.headers.authorization) {
      req.headers.authorization = 'Bearer guest-token';
    }
    return next();
  }

}

然后在Express Setup的某处

setupRouters() {
    // the public and admin routers are bound to the application
    const coreCtrl = new CoreCtrl(this.serverOpts);
    const anonymousCtrl = coreCtrl.simulateAnonymous.bind(coreCtrl);
    this.routers.admin.use(anonymousCtrl);
    this.routers.admin.use(passport.authenticate('UserBearer', { session: false }));
    this.routers.public.use(anonymousCtrl);
    this.routers.public.use(passport.authenticate('CustomerBearer', { session: false }));
  }

请注意,我在这里设置了单独的公共和管理员路由器,这不是必需的,只是为了说明如何操作。

然后在承载策略中,您将获得与此类似的代码。

/**
* Run the strategy
*
* @param token {String} The JWT Token
* @param done {Callback} Callback function
*/
exec(token:string, done):Promise<any> {
  // this is the workaround to support not passing a token for guest users.
  if (token === 'guest-token') {
    return done(null, {
      userId: 'guest',
      roles: ['guest']
    });
  }
  // otherwise decode the token and find the user.
}

最后,在稍后的某些中间件中,您可以检查“访客”是否已经过了。 role可以访问受保护的资源。我建议acl模块来管理基于角色的ACL列表。