0%

Express 使用 Passport-Facebook 驗證,串接 Graphy Api

前言

近期開始再玩 Express, 發現一個很好用的 authentication middleware (Passport ) ,
Passport 是一套整合很多驗證的模組, 例如: Login, Fb, Google… 等,
讓我們能快速開發登入功能, 是一個整合不錯的套件。

操作步驟

Step1:

要使用 Fb 登入驗證, 需要至 Facebook-Developer 註冊一個 App。

Step2:

安裝需要的模組

1
npm install --save express express-session mongoose passport passport-facebook request-promise

Step3:

撰寫 passport-facebook 的 Strategy, 使用者登入成功後, 會呼叫此驗證策略,
並取得使用者的資料以及 access_token, 透過 access_token 我們可以用 fb 的
graphy api 取得一些使用者的資訊

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

//file: passport.js

var passport = require('passport'); //passport 模組
var FaceBookStrategy = require('passport-facebook').Strategy; //facebook 驗證
var request = require('request-promise'); //request 模組


module.exports = function(passport) {
passport.use(new FaceBookStrategy({
clientID:'your client id',
clientSecret:'your client secret',
profileFields:['email','displayName'], //取得使用者資料的哪些欄位,並回傳至 callback 的 profile 參數
callbackURL:'auth/facebook/callback', //登入成功導回至哪個 url
passReqToCallback:true //是否要傳 request 至 callback
},(req, token, refreshToken, profile, done)=>{ //第一個參數 req 取決於 passReqToCallback 是 true or false, true 則會傳入至 callback

// 取得 graphy api user 的哪些欄位
const userFieldSet = 'id, name, about, email, accounts, link, is_verified, significant_other, relationship_status, website, picture, photos, feed';
const options = {
method: 'GET',
uri: `https://graph.facebook.com/v2.11/me`,
qs: {
access_token: token,
fields: userFieldSet
},
json:true //true 的話會自動將資料做 JSON.parse
};
request(options)
.then(fbRes => {
console.log(fbRes);
return done(null,fbRes);
});
}));
}

Step4:

撰寫路由的部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//file: index.js

var passport = require('passport'); //passport 模組
var session = require('express-session');
var mongoose = require('mongoose');
var express = require('express');
var app = express(); //建立 express app

require('passport')(passport) //引用剛剛寫的 Fb 驗證策略

mongoose.Promise = global.Promise; //解決錯誤訊息()
mongoose.connect('dbUrl'); //連線 mongodb

app.use(session({
secret:"This is myTest key",// 設定 secret 計算 hash 值並放在在 cookie 中,產生的 signedCookie 防竄改
resave:false, //不要更新 session
saveUninitialized:false ,// 設定 false,強制建立一個 session,即使用户未登入
store:new MongoStore({mongooseConnection:mongoose.connection}) //將 session 存到 mongodb
}));

app.use(passport.initialize()); //初始化 passport 驗證
app.use(passport.session()); //passport 啟用 session

//首頁
app.get('/',(req,res,next)=>{
res.render('index',{title:'Index'});
});

//fb 登入動作
app.get('/auth/facebook',passport.authenticate('facebook',{ //使用剛剛撰寫的 facebook 驗證策略
scope:['email','user_about_me','user_location','user_photos','user_posts'] //要求權限
}));

//fb 驗證策略做完,回傳的 callback
app.get('/auth/facebook/callback',passport.authenticate('facebook',{
successRedirect : '/home', //成功導頁至
failureRedirect : '/login', //失敗導頁至
failureFlash : true //失敗或自動刷新
}));

Step5:

view 的部分

1
2
3
4
<!--file: index.ejs-->
<a href="/auth/facebook" class="form-control btn btn-primary">
<i class="fa fa-facebook"></i>signup with facebook
</a>

參考連結:

官方教學
Express+Passport+Graphy Api
Graphy Api Doc
Graphy Api Permission