passport的验证过程主要依赖具体的验证策略来实现的,比较经常使用的有session策略、local策略和github策略等,验证逻辑都是在这些策略类中定义的。passport模块的定义主要包括三个部分:passport类、相关中间件和验证策略,passport自带了session验证策略,若是要使用其余验证策略,须要自行添加。git
passport的使用分为五个部分:github
app.use(passport.initialize())
对passport进行初始化,不然后面的验证方法没法执行app.use(passport.session());
,这个主要是为了记住用户的登陆状态,能够指定session过时时间本文没有对passport进行深刻的分析,具体请参考注释版源码。express
依赖于 ./framework/connect
和 ./strategies/session
主要属性:session
this._key = 'passport'; //挂载在session上的关键字 this._strategies = {}; //保存全部验证策略的对象 this._serializers = []; //序列化session this._deserializers = []; //反序列化session this._infoTransformers = []; this._framework = null; //保存全部中间件的对象 this._userProperty = 'user'; //挂载在req上的关键字 req.user
进行相关初始化,添加authenticate和initialize中间件,添加session验证策略 。给req对象添加login、logout、isAuthenticated和isUnAuthenticated方法app
passport暴露的中间件是相似于connect风格的,签名如:fn(req, res, next)
,而有的框架须要的是不一样的签名风格,所以,该方法是用来作适配的,若是使用的是express框架,则不须要调用该方法。将传入的参数保存到this._framework中,参数以下:框架
{ initialize: initialize, authenticate: authenticate }
添加具体验证策略对象,并保存到this._strategies中,策略对象必须提供名称,例如:
passport.use('local',new LocalStrategy(function(username,password,done){ //todo });
函数
根据策略名称,删除this._strategies中对应的验证策略对象,例如:passport.unuse('local');
this
设置this._userProperty,而后调用this._framework.initialize方法生成一个初始化中间件,并返回该中间件prototype
调用this._framework.authenticate方法生成一个验证中间件,并返回该中间件code
主要包括initialize和authenticate,除此以外,在加载的时候还会对req对象定义多个方法
进行相关初始化工做,将session中的passport对象(req.session[passport._key])挂载到req._passport上,若是session中没有保存相关信息或者session为空,则req_passport={}
给验证策略添加了额外的处理方法,如:success、fail、redirect、pass、error,主要目的是对验证状态进行保存。有了这些方法,咱们就能够只关心验证逻辑的定义,在验证成功或失败后只需调用这些预先定好的方法便可。该中间件对请求按照指定的策略进行验证,若是验证经过,调用success方法,用户就会登陆成功,相关用户信息将被挂载到req.user上同时会生成一个session对象,若是验证失败,将会向客户端发送未受权响应。
该中间件须要注意的地方就是验证回调,若是提供了回调函数,那么将会覆盖默认的处理方式,即:attemp方法,此时须要自行调用req.login
//提供了回调函数的状况 app.get('/login', function(req, res, next) { passport.authenticate('local', function(err, user, info) { if (err) { return next(err); } if (!user) { return res.redirect('/login'); } req.logIn(user, function(err) { if (err) { return next(err); } return res.redirect('/users/' + user.username); }); })(req, res, next); });