[ Day 9]
說明:
目前的各動態網站幾乎都有會員機制,對不同身分的使用者提供不一樣的內容,
這時需要一個安全的身分驗證機制,否則很容易讓網站被入侵竊取資料。
一、Passport.js
根據官網,passport.js是一個提供了超過500種驗證方式的套件,
其中包含了常見的Facebook,google等第三方提供auth,或是使用自己建立的bearer token等等驗證方式,
而passport.js則是作為middleware中間件。
二、passport-local
先嘗試看看passport-local,使用最常見的username和password方式進行身分驗證
這是最早期也最普遍的身分驗證方式了,但需注意在現在的網路環境底下,這種方式不一定安全
先安裝passport以及passport-local
npm install passport passport-local --save
必須引入的套件:
const passport = require('passport')
const LocalStrategy = require('passport-local')
const bodyParser = require('body-parser');
const express = require('express');
const app = express()
const port = 3310
說明:
passport使用時,還需決定要使用的stategy,在這裡用的是localstrategy,所以兩個都需引入
另外express和passport本身不具有解析傳入參數的能力,所以需要使用bodyparser進行參數解析
app.use(passport.initialize())
//app.use(passport.session())
app.use(bodyParser.urlencoded({ extended: true }))
在express中使用passport middleware
針對user進行序列化:
passport.serializeUser(function (user, cb) {
cb(null, user);
});
passport.deserializeUser(function (id, cb) {
cb(null, id)
});
說明:
這裡有兩個方法,一是將user傳入後,在callback function中再行操作,一般會將user的資訊儲存再session中,但此處先跳過
二是當傳入id後進行的user反序列化的方法。
註冊passport的認證strategy
passport.use(new LocalStrategy(
function (username, password, done) {
console.log(username + ' ; ' + password)
var user = { username: username };
return done(null, user);
}
));
說明:
指定了LocalStrategy這個物件,有個匿名function當接收到username和password後要如何處理
最後返回done,包含了user物件(當之後有需要針對不同的驗證後的物件回傳,需寫在第三個參數)
註冊login url,包含驗證方式
app.post('/login',
passport.authenticate('local', { failureRedirect: '/register' }),
function (req, res) {
res.redirect('/');
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
這裡指定login url接收到request後,進行passport的驗證,
當失敗後會failureRedirect,重導到/register此url
成功後會重導到'/' 根目錄
三、加入資料庫,在資料庫查詢使用者
passport.use(new LocalStrategy(
function (username, password, done) {
console.log(username + ' ; ' + password)
knex('user').select('*')
.where('user_name', username)
.andWhere('password', password)
.then((resultArray) => {
if(resultArray.length < 1) {
return done(null, user, {'message': '帳號或密碼輸入錯誤'});
} else {
var user = { username: username, userId: resultArray[0].user_id};
return done(null, user, {'message': '登入成功'});
}
}).catch((error) => {
return done(null, false, {'message': error});
})
}
));
app.post('/login', function(req, res, next){
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err) }
if (!user) { return res.json( { message: info.message }) }
res.json(user);
})(req, res, next);
});
待續...
[Day9結束]