passport.js是Nodejs中的一个做登录验证的中间件,极其灵活和模块化,并且可与Express等Web框架无缝集成。Passport功能单一,即只能做登录验证,但非常强大,支持本地账号验证和第三方账号登录验证(OAuth和OpenID等),支持大多数Web网站和服务。
首先你需要Nodejs,然后数据库用来存储用户数据;另外passport作为中间件,需要依赖Express和Connect.
具体的依赖有:
Express:web框架。或其他支持的框架。
Connect:中间件框架。
cookie-parser:Connect的cookie解析中间件。
express-session:Connect的session解析中间件,依赖于cookie-parser。
express-flash:express的消息提示中间件,可选,但一般情况下都需要装。
你最少需要安装一个passport策略来使用它,一般而言本地验证策略passport-local是必装的。
npm install passport npm install passport-local var express = require('express'); var cookieParser = require('cookie-parser'); var session = require('express-session'); var flash = require('express-flash'); var passport = require('passport'); ... app.use(cookieParser()); app.use(session({...})); app.use(passport.initialize()); app.use(passport.session()); app.use(flash())
var passport = require('passport') , LocalStrategy = require('passport-local').Strategy; passport.use(new LocalStrategy( function(username, password, done) { User.findOne({ username: username }, function(err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: '用户名不存在.' }); } if (!user.validPassword(password)) { return done(null, false, { message: '密码不匹配.' }); } return done(null, user); }); } ));
这里用的是mongodb数据库。
验证回调需要返回验证结果,这是由done()来完成的。
在passport.use()里面,done()有三种用法:
当发生系统级异常时,返回done(err),这里是数据库查询出错,一般用next(err),但这里用done(err),两者的效果相同,都是返回error信息;
当验证不通过时,返回done(null, false, message),这里的message是可选的,可通过express-flash调用;
当验证通过时,返回done(null, user)。
上面的代码里是user.validPassword(password)方法,这并不是passport添加的,而是需要用户自定义。
一般对密码进行哈希和盐化的Nodejs模块是bcrypt,它提供一个compare方法来验证密码,如何使用它则超出本文的范围,这里就不讲了。
session序列化与反序列化
验证用户提交的凭证是否正确,是与session中储存的对象进行对比,所以涉及到从session中存取数据,需要做session对象序列化与反序列化。调用代码如下:
passport.serializeUser(function(user, done) { done(null, user.id); }); passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); }); });
这里第一段代码是将环境中的user.id序列化到session中,即sessionID,同时它将作为凭证存储在用户cookie中。
第二段代码是从session反序列化,参数为用户提交的sessionID,若存在则从数据库中查询user并存储与req.user中。
我所讲述的passport.js 只是一小部分,详情请看:http://idlelife.org/archives/808