2017-05-15 85 views
1

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

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

我使用从快递Request对象:

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

我需要使用不同的Request对象?

此外,如果我需要强制认证到某些api路由,但锁定其他路由,应如何使用passport-jwt完成此操作?我知道有一个快递 - 除非可以用于express-jwt。

+0

运行此代码时您是否收到错误消息,或者您的问题是关于intellisense的问题? Javascript不容易静态分析,所以intellisense有很多东西无法提取 –

+0

它正在变成红色的intellisense,当我mouseover我得到“未解决的变量用户”。我认为,因为我使用打字稿,它会找到变量。 – user1790300

+0

我不认为intellisense会变得聪明,对不起让人失望。这一切仍然是新的,有些部分仍然未知。部分与新技术合作:) –

回答

1

不知道为什么这个问题downvoted,也许是因为它应该是两个单独的问题。

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

扩展快递类型定义

添加文件library-ext.d.ts与此源目录。

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

对于req.header.authorization请尝试:req.headers ['authorization']。注意's'。

与一般认证

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

更复杂的情况是,当您需要经过身份验证的用户和未经身份验证的用户都可以访问路线时 - 请考虑客人或经过身份验证的客户将某物添加到购物车。不幸的是passport-jwt当令牌不在授权标题中时拒绝401,所以我发现最简单的方式,而不是分支项目或者滚动我自己的策略,就是使用中间件添加一个已知值来表示匿名请求。然后确保中间件在受影响路由中的护照认证之前。这里有一个片断,让你去:

CoreCtrl

class CoreCtrl { 

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

} 

然后在某处你快速安装

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

最后,在稍后的一些中间件中,您可以检查'guest'角色是否可以访问受保护的资源。我建议使用acl模块来管理基于角色的ACL列表。

相关问题