前言 接下來將會來講如何設置會員機制,但是這邊將會使用到的是 firebase 的會員驗證機制
起手式 這邊就不附上如何快速產生 Express 的方式了,因為這邊我會直接使用 Express 產生器來產生。
直接跳到開啟 Firebase 後台,然後點一下 Authentication
點一下 登入方式,並將以下方法打開
這邊我也直接放是我會使用的套件
1 npm install --save express-session nodemailer connect-flash csurf express-validator dotenv
app.js 內容也一併附上(很長)
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 var createError = require ('http-errors' );var express = require ('express' );var path = require ('path' );var session = require ('express-session' );var cookieParser = require ('cookie-parser' );var bodyParser = require ('body-parser' );var flash = require ('connect-flash' );var csurf = require ('csurf' );var logger = require ('morgan' );var indexRouter = require ('./routes/index' );var usersRouter = require ('./routes/users' );var authRouter = require ('./routes/auth' );var csrfProtection = csurf ({ cookie : true });var app = express ();app.set ('views' , path.join (__dirname, 'views' )); app.set ('view engine' , 'ejs' ); app.use (logger ('dev' )); app.use (express.json ()); app.use (express.urlencoded ({ extended : false })); app.use (cookieParser ()); app.use (session ({ secret : 'keyboard cat' , resave : false , saveUninitialized : true , })) app.use (flash ()); app.use (bodyParser.urlencoded ({ extended : false })) app.use (bodyParser.json ()) app.use (express.static (path.join (__dirname, 'public' ))); app.use ('/' , indexRouter); app.use ('/users' , usersRouter); app.use ('/login' ,csrfProtection ,authRouter); app.use (function (req, res, next ) { next (createError (404 )); }); app.use (function (err, req, res, next ) { res.locals .message = err.message ; res.locals .error = req.app .get ('env' ) === 'development' ? err : {}; res.status (err.status || 500 ); res.render ('error' ); }); module .exports = app;
接下來這邊還有一個重點,我們要使用 firebase 的登入認證之前還必須安裝一個套件,也就是 firebase-admin
還要建立 .env,如果不清楚可以看這篇 詳細說明
大致上操作都與上面這篇文章雷同,所以大致上結構會像這樣
Router 目前 auth 內容只有這樣子
1 2 3 4 5 6 7 8 9 var express = require ('express' );var router = express.Router ();router.get ('/' , function (req, res, next ) { res.render ('index' , { title : 'Express' }); }); module .exports = router;
在這邊 res.render
我們 index
要修改成 login
1 2 3 router.get ('/' , function (req, res, next ) { res.render ('login' , { title : '登入畫面' }); });
而 EJS 頁面非常簡單,只是一個單純登入而已,基本上執行起來畫面就像這樣
除了登入我們也要製作註冊的 router,這邊 EJS 一樣我就忽略了,因為比較沒有什麼
1 2 3 4 5 6 7 8 9 10 router.get ('/signup' , function (req, res, next ) { res.render ('signup' , { csrfToken : req.csrfToken (), title : '註冊帳號' }); }); router.post ('/signup' , function (req, res, next ) { res.render ('signup' , { title : '註冊帳號' }); });
製作註冊 router 接下來就來開始製作註冊帳號的 router,首先要先接上 firebase,透過 firebase 本身提供的 API createUserWithEmailAndPassword
來建立帳號,但是在那之前必須先確保 signup 頁面的表單資料會正確的傳到伺服器,所以可以這樣測試
1 2 3 4 router.post ('/signup' , function (req, res, next ) { console .log (req.body ); res.render ('signup' , { title : '註冊帳號' }); });
如果正確接收到就會像這樣 (密碼欄位不用擔心,進入 firebase 的時候會加密,所以不可能取得)
firebase-connect 確保表單資料有傳到伺服器後就可以開始實作註冊帳號哩,但是在那之前必須先連結 firebase,這邊你可能會覺得很詭異,前面不是已經載入一個 firebaseAdmin 了嗎?為什麼還要載入一個 firebase?
首先我們載入的 firebaseAdmin 主要是提供授權方面
那個接下來要設置的是 firebase-connect,這個功能可以呼叫各種 firebase 的 API,舉凡稍後我們要做的註冊帳號,所以首先先建立一個檔案叫 firebase-connect.js 於 connection 資料夾下
那麼內容的取得在 專案設定 中
然後拉到下方可以看到 Firebase SDK snippet,在這邊我們不會使用 CDN 得方式
這邊我們所有資料都是採用 env 環境變數所傳入,另外這邊還要安裝一個套件,在前面文章沒有講到
1 npm install --save firebase
然後將 .env 改成以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # Firebase Admin FIREBASE_DATABASEURL= FIREBASE_TYPE= FIREBASE_PROJECT_ID= FIREBASE_PRIVATE_KEY_ID= FIREBASE_PRIVATE_KEY= FIREBASE_CLIENT_EMAIL= FIREBASE_CLIENT_ID= FIREBASE_AUTH_URL= FIREBASE_TOKEN_URL= FIREBASE_AUTH_PROVIDE_X509_CERT_URL= FIREBASE_CLIENT_X509_CERT_URL= # Firebase connect FIREBASE_API_KEU= FIREBASE_AUTH_DOMAIN= FIREBASE_MESSAGINGSENDERID= FIREBASE_STORAGEBUCKET= FIREBASE_APPID
並且將剛剛取得得 Firebase SDK snippet 及內容改成以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 var firebase = require ('firebase' );require ('dotenv' ).config ();var firebaseConfig = { apiKey : process.env .FIREBASE_API_KEY , authDomain : process.env .FIREBASE_AUTH_DOMAIN , databaseURL : process.env .FIREBASE_DATABASEURL , projectId : process.env .FIREBASE_PROJECT_ID , storageBucket : "" , messagingSenderId : process.env .FIREBASE_MESSAGINGSENDERID , appId : process.env .FIREBASE_APPID }; firebase.initializeApp (firebaseConfig); module .exports = firebase;
接下來在 auth.js 中引入 firebase,並將 router 改成以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 router.post ('/signup' , function (req, res, next ) { var email = req.body .email ; var password = req.body .password ; firebase.auth ().createUserWithEmailAndPassword (email, password) .then (function ( ){ res.redirect ('/login/signup' ) }) .catch (function (error ) { var errorCode = error.code ; var errorMessage = error.message ; console .log (errorCode, errorMessage); res.redirect ('/login/signup' ) }); });
接下來就可以試著註冊看看,註冊成功的話就可以在後台看到剛剛註冊得帳號哩
最後我使用 flash
將註冊成功與否訊息往前傳給使用者,所以最終 router 是這樣
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 router.get ('/' , function (req, res, next ) { res.render ('login' , { title : '登入畫面' }); }); router.get ('/signup' , function (req, res, next ) { res.render ('signup' , { success : req.flash ('info' ), csrfToken : req.csrfToken (), title : '註冊帳號' }); }); router.post ('/signup' , function (req, res, next ) { var email = req.body .email ; var password = req.body .password ; firebase.auth ().createUserWithEmailAndPassword (email, password) .then (function ( ) { req.flash ('info' ,'註冊成功' ); res.redirect ('/login/signup' ); }) .catch (function (error ) { var errorCode = error.code ; var errorMessage = error.message ; req.flash ('info' , errorMessage); res.redirect ('/login/signup' ); }); });