轉載自樓主我的博客 使用 passport.js 來完成登陸驗證 - 2016/6/22javascript
先囉嗦一段背景java
介紹一下項目所使用的技術棧。Node.js
,使用 Express
來完成後端服務器的架構,這個時候就遇到了一個問題了。在我之前,是用 Java
來開發 Web 後端服務器,那時我採用 Spring
框架來完成,登陸的驗證就是比對數據庫中的用戶名密碼與當前用戶所輸入的用戶名密碼,並且若是但願攔截未登陸的用戶的訪問某些特定的網址時,我能夠添加 Spring
自定義的攔截器實現來實現用戶未成功驗證時的攔截。可是如今我使用的是 Node.js
來完成開發,不知道該怎麼作了,沒辦法只好 google 一下了,結果推薦較多的就是 passport.js
。git
這個時候已經肯定就使用這個 js 庫了,好的,開工!可是問題來了,我該怎麼使用呢,官方是有文檔,英文倒也還好,但總感受就是有那麼點不夠清晰,有些細節不必定能好好的解決,爲了方便更多人使用這個框架,通過配置成功之後,想把這個的經驗分享出來,好了,進入正題~github
默認使用的環境就是 express
搭建的服務器。數據庫
# passport 須要 session 的支持, #因爲使用的是 express.js,因此這裏使用 express-session npm install express-session --save # 固然要下載 passport …… npm install passport --save # passport支持一系列的 OAuth 第三方驗證, #而咱們通常的使用場景爲驗證本身項目中的用戶 #,因此這裏使用 passport-local npm install passport-local --save
先搭建好服務器用於 passport
的配置,加上 session
的配置,其中 passport-config.js
文件先導入無論具體實現,不影響個人描述,稍後將在下方給出詳細配置方法。express
/** * /server.js */ import express from 'express'; import expressSession from 'express-session'; // 導入一個咱們配置好了 passport 的 js 文件 import passport from '../core/passport-config'; const server = express(); // ... 不相干的 express 的配置 // 配置 session,passport 所需的基礎,必須有 server.use(expressSession({ // 你喜歡的任意名字做爲一個加密用的字符串 secret: 'whatever the name you like', resave: false, saveUninitialized: false })); // 初始化調用 passport server.use(passport.initialize()); server.use(passport.session()); //
到這裏爲止,咱們在服務器上的設置就完成了,接下來看看如何配置 passport
。npm
我把代碼的做用寫在瞭如下代碼的註釋中,裏面詳細講述了大體的原理及做用。後端
/** * /core/passport-config.js */ import passport from 'passport'; import LocalStrategy from 'passport-local'; // 這裏引入的是一個操做數據庫的 User 工具函數 import User from '../model/User'; // 這個配置就是參照官方示例來的,不過官方的講解不夠詳細 // 我將在這裏詳細講講是怎樣獲取用戶並驗證是否正確 passport.use(new LocalStrategy( /** * @param username 用戶輸入的用戶名 * @param password 用戶輸入的密碼 * @param done 驗證驗證完成後的回調函數,由passport調用 */ function (username, password, done) { // 在編寫 User.findUniqueUserByUsername 時,包含兩個參數,一個是 username // 一個是咱們如今所傳入的回調函數,咱們將獲取到的用戶信息傳遞給咱們的回調函數 User.findUniqueUserByUsername(username, function (err, user) { if (err) { console.log('出現錯誤.'); return done(err); } if (!user) { console.log('沒有找到對應的用戶名.'); return done(null, false, {message: '沒有找到對應的用戶名.'}); } if (user.password != password) { console.log('密碼匹配有誤.'); return done(null, false, {message: '密碼匹配有誤.'}); } return done(null, user); }); } )); // serializeUser 在用戶登陸驗證成功之後將會把用戶的數據存儲到 session 中(在這裏 // 存到 session 中的是用戶的 username)。在這裏的 user 應爲咱們以前在 new // LocalStrategy (fution() { ... }) 中傳遞到回調函數 done 的參數 user 對象(從數據// 庫中獲取到的) passport.serializeUser(function (user, done) { done(null, user.username); }); // deserializeUser 在每次請求的時候將會根據用戶名讀取 從 session 中讀取用戶的所有數據 // 的對象,並將其封裝到 req.user passport.deserializeUser(function (username, done) { User.findUniqueUserByUsername(username, function (err, user) { if (err) { return done(err); } done(null, user); }); }); // 這是封裝了一箇中間件函數到 passport 中,能夠在須要攔截未驗證的用戶的請求的時候調用 passport.authenticateMiddleware = function authenticationMiddleware() { return function (req, res, next) { if (req.isAuthenticated()) { return next(); } res.redirect('/login'); } }; export default passport;
到此基本的配置到此結束,以個人經驗,這足以來完成基本的驗證使用了。bash
接下來說講如何在 server.js 中使用咱們上面配置好的 _passport.js_, 咱們在 配置服務器 中已經加載並使用了咱們的配置,如今讓咱們看看如何在咱們的路由中使用它。服務器
// ------------ // server.js // ------------ import passport from '../core/passport-config'; // 以下所示,咱們在路由的請求地址 「/login」 和 後續的請求處理函數之間調用 // passport.authenticate('local'),便可完成對用戶輸入的用戶名密碼的驗證 server.post('/login', passport.authenticate('local'), function (req, res) { // req.user 中會包含在 deserializeUser 函數中傳入的 user 數據 console.log("-------req.user-----------"); console.log(req.user); console.log("-------req.user-----------"); let returnData = { isSuccess: true, uer: req.user }; res.send(JSON.stringify(returnData)); }); // 調用咱們以前在 passport-config 中封裝的用於驗證用戶是否已經被驗證的中間件函數 // 便可限制未被驗證的用戶不能請求該路由,返回 Error: 401(Unauthorized) server.get('/testAuth', passport.authenticateMiddleware(), function(req, res) { // ...... });
通過實例代碼咱們知道了如何配置以及使用 passport。解釋內容請讀者留心代碼註釋。