請關(guān)注專題:我的NodeJS學習之路(實踐之路)
小弟初涉node領(lǐng)域,不足之處,還請多多指教!
歡迎Star、Fork:https://github.com/gefangshuai/ANodeBlog
本文來介紹系統(tǒng)中用到的權(quán)限認證的知識。
首先簡單介紹一下passportjs。
Passport做登錄驗證具有:靈活性、模塊化、豐富的中間件等特點,更加詳細的介紹請參考:http://idlelife.org/archives/808
如何在項目中使用passport?
注意:關(guān)于passport的配置信息要放置在
app.js所有的路由請求上面,這樣才能對所有的路由進行過濾。
1. 安裝集成
npm install passport --save
我們還用到了本地驗證策略,所以將passport-local一起安裝
npm install passport-local --save
2. 配置passport
- 在項目中引用
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
- 對策略進行配置
passport.use(new LocalStrategy(callback_function)));
**callback_function: **
三個參數(shù)分別是:username、password、done。
-
username:需要驗證的“用戶名” -
password:需要驗證的“密碼” -
done: 對驗證結(jié)果的處理方法
username和password默認對應(yīng)表單的name="username"和name="password",也可以自己定義表單的名字,比如:
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'passwd'
},
function(username, password, done) {
// ...
}
));
關(guān)于done函數(shù):
- 處理成功,
return done(null, user) - 處理失敗
return done(err)或者return done(null, false)或者return done(null, false, { message: 'Incorrect password.' })
- 對Session進行序列化和反序列化
序列化:
即:將唯一的值(如登錄用戶的id)序列化到session中,即sessionID,同時它將作為憑證存儲在用戶cookie中。
passport.serializeUser(function (user, done) {
done(null, user.id);
});
反序列化:
即:根據(jù)存在的sessionID,從數(shù)據(jù)庫中查詢user并存儲與req.user中。
passport.deserializeUser(function (id, done) {
done(null, id);
});
做完以上三步,就已經(jīng)簡單地將passport集成在項目中了。
3. 做登錄處理
在處理登陸請求的路由中,加入登錄處理的配置信息,然后passport會自動幫你處理是否登錄成功(有點類似shiro)。
router.post('/login', passport.authenticate('local', options), success_callback);
options可以定義的參數(shù):
-
session:Boolean。設(shè)置是否需要session,默認為true -
successRedirect:String。設(shè)置當驗證成功時的跳轉(zhuǎn)鏈接 -
failureRedirect:String。設(shè)置當驗證失敗時的跳轉(zhuǎn)鏈接 -
failureFlash:Boolean or String。設(shè)置為Boolean時,express-flash將調(diào)用use()里設(shè)置的message。設(shè)置為String時將直接調(diào)用這里的信息。 -
successFlash:Boolean or String。使用方法同上。
success_callback:驗證成功后做的處理,可以是登錄成功后的跳轉(zhuǎn)等等。
4. 在方法中使用校驗
使用其實很簡單,passport擴展了http request默認提供了一些內(nèi)置方法:
-
request.logIn(user, options, callback): 將登錄用戶存入session。
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/users/' + user.username);
});
這樣,就可以通過req.user獲取user對象了
-
request.logOut():退出登錄用戶,刪除session信息。 -
request.isAuthenticated():判斷當前請求的用戶是否已授權(quán)(已登錄),返回true或false -
request.isUnauthenticated():跟request.isAuthenticated()相反。
有了上面的知識,我們就可以統(tǒng)一進行驗證了。
如:對于后臺管理的模塊,必須登錄用戶才能有權(quán)限,所以可以對后臺管理的所有路由進行攔截,為了方便我們可以自定義一個中間件來統(tǒng)一進行處理:驗證通過,繼續(xù);驗證不通過,跳回到登錄頁面,并告知需要登陸。
5. 封裝驗證中間件:(authority.js)
module.exports = {
/**
* 登陸權(quán)限驗證
*/
isAuthenticated: function (req, res, next) {
if(req.isAuthenticated()) {
return next();
}else{
req.flash(config.constant.flash.error, '請先登錄!');
res.redirect('/login')
}
}
};
6. 統(tǒng)一對路由進行過濾
app.use('/dashboard', authority.isAuthenticated, require('./routes/dashboard'));
app.use('/dashboard/p', authority.isAuthenticated, require('./routes/dashboard-p'));
app.use('/dashboard/u', authority.isAuthenticated, require('./routes/dashboard-u'));
關(guān)于passport-local的實用實例,在官方wiki有給出,可以做一下參考。
請關(guān)注專題:我的NodeJS學習之路(實踐之路)