passport
是一个为Nodejs
设计的,兼容Express
的认证中间件。通过第三方插件的形式(以下称为strategy
),可以应对各式各样的认证请求。passport
具有高度的灵活性,并不依赖于任何一个路由,或者指定的数据存储,这样给上层开发者提供的极大的便利性。passport
提供的接口也相对简单,只需要给它一个认证请求,passport
会提供一个钩子函数(hook
)告诉你请求失败了或者成功了。
1. passport的设计思路
passport
基于一个高度灵活的设计结构,主要由四个模块组成:passport
插件(strategy)管理模块、执行认证操作的授权模块
、framewark适配模块
、session管理模块
。其结构框图如下:
授权流程(引用github oath2.0
来举例)
1.授权插件体系
所有的passport
插件都继承自passport-strategy
,紧接着根据不同的授权流程又细分为OAuth2.0授权中间件、OPENID类的授权中间件、以及帐号密码类的授权中间件。这些基本的中间件官方已经有了标准的实现。开发者需要做的是去继承这些授权中间件,针对不同的业务需求,配置特定的部分参数。就可以完成一整个授权的流程。常见的OAth2.0标准的授权插件有:passport-github
、passport-twitter
。这些针对不同厂商的第三方Strategy
体量都非常小,基本在100行代码内可以搞定,因为大部分工作都交给标准的strategy
来做了。
2.framework适配
passport
官方的实现基于标准的Express
形式的风格,也就是说,中间件的函数风格类似于:
function authenticate(req, res, next)
如果需要适配其他的框架需要实现特定风格的authenticate
函数。
3. session管理
passport
提供session的功能,如果开启该功能,则需要提供序列化,以及反序列化接口。express-session
是一个很好的session管理包,所以还是让passport
专注于授权认证吧!
2. passport使用
1. 注入第三方strategy
function verifyProfile(accessToken, refreshToken, profile, done) {
profile.accessToken = accessToken;
done(null, profile);
}
passport.use(new GithubStrategy({
clientID: '123-456-789',
clientSecret: 'easdasjdklasjd',
callbackURL: 'http://www.example.com/auth/github/callback'
}), verifyProfile);
passport提供use
函数用于注入授权认证的插件、unuse
用于注销认证插件。verifyProfile
接口是一个hook
,用来验证用户信息的有效性。
2. 授权认证
//请求授权码
app.get('/user/login/github', passport.authenricate('github', {scope: 'wl_scope'}));
//获取accessToken以及请求用户信息,关闭session功能
app.get('/auth/github/callback', passport.authenricate('github', {session: false, failureRedirect: '/'}));
3. passport源码分析
1. 授权认证入口函数
Authenticator.prototype.authenticate = function(strategy, options, callback) {
return this._framework.authenticate(this, strategy, options, callback);
};
2. express 风格的认证函数
module.exports = function authenticate(passport, name, options, callb