前言
前面基本 UI 及 Rotue 已經建立完畢,所以現在就要來準備將剛剛安裝的套件給加入至 app.js 中
回憶階段
首先先回頭想一下我們安裝了那些插件,這樣子才知道要設定那些
- express-session - session 套件
- nodemailer - 發送電子郵件套件
- connect-flash - 快取套件
- csurf - CSRF 防禦
- express-validator - 欄位驗證,前面沒有講到,所以順便這章節實作來講
- body-parser - 解析表單欄位
- dotenv - 環境變數
dotenv
先在可能會需要使用環境變數的 users.js 引入環境變數語法
1
| require('dotenv').config();
|
並且在根目錄建立 .env
檔案內容如下
express-session
首先先將 express-session 的相關設定寫入至 app.js 中
1 2 3 4 5 6
| var session = require('express-session'); app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true, }))
|
connect-flash
我先跳過了 nodemailer 的設置,因為這裡面有一些東西要先做調整
也是一樣將 connect-flash 寫入至 app.js 中
1 2
| var flash = require('connect-flash'); app.use(flash());
|
csurf
絕對少不了 csurf 的套件,也是相同都是在 app.js 引入
1 2
| var csurf = require('csurf') var csrfProtection = csrf({ cookie: true })
|
那由於是 middleware 的關係,所以我先調整一下 router 加入 middlew加入
1 2
| app.use('/',csrfProtection ,indexRouter); app.use('/users',csrfProtection ,usersRouter);
|
也要記得隱藏欄位並帶上 name="_csrf" value="{{csrfToken}}"
,要注意不能用 {{csrfToken}}
在 EJS 下要這樣使用 <%= csrfToken %>
另外還要修改 get route,否則會出現 no defined
1 2 3 4 5 6
| router.get('/mailsend',function(req, res, next) { res.render('users', { title: '信件發送頁面', csrfToken: req.csrfToken() }); });
|
body-parser
這是一個超級重要的套件,要是沒有這個套件就不能解析表單元素,一樣 app.js 引入
1 2 3
| var bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json());
|
nodemailer
接下到了設置發送電子郵件的套件,但是這一個套件只會在特定的 route 使用,所以只會在 users.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
| var nodemailer = require("nodemailer");
router.post('/mailsend',function(req, res, next) { var transporter = nodemailer.createTransport({ service: 'Gmail', auth: { user: process.env.ACCOUNT, pass: process.env.PASSWORD, } }); var mailOption = { form: '"測試電子郵件"<xxx@gmail.com>', to: req.body.email, subject: req.body.username + '你好!測試一封測試信', text: req.body.content } transporter.sendMail(mailOption ,function(error, info) { if (error) { console.log('錯誤訊息:' + error); res.redirect('/users/mailsend'); } console.log('發送成功'); res.redirect('/users/mailsend'); }) res.send('Hello!'); });
|
express-validator
express-validator 只會有幾個地方使用,所以直接在 route 中引入即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var validat = [ check('email').isEmail().withMessage('Email 錯誤'), check('username').isLength({ min: 2 }).withMessage('姓名不可低於 3 個字元'), check('content').isLength({ min: 10 }).withMessage('字數不可少於 10 字元') ] router.post('/mailsend' ,validat ,function(req, res, next) { var errors = validationResult(req); if (!errors.isEmpty()) { return res.status(422).render('users', { title: '信件發送頁面', csrfToken: req.csrfToken(), errorMessages: errors.array(), }) } ...(以下略)
|
可透過 withMessage
自訂提示訊息
這邊其實可以優化一下改用 flash 來做提示訊息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| router.get('/mailsend',function(req, res, next) { res.render('users', { title: '信件發送頁面', csrfToken: req.csrfToken(), errorMessages: req.flash('errorMessages') }); });
var validat = [ check('email').isEmail().withMessage('Email 錯誤'), check('username').isLength({ min: 2 }).withMessage('姓名不可低於 3 個字元'), check('content').isLength({ min: 10 }).withMessage('字數不可少於 10 字元') ] router.post('/mailsend' ,validat ,function(req, res, next) { var errors = validationResult(req); if (!errors.isEmpty()) { req.flash('errorMessages',errors.array()) res.redirect('/users/mailsend') } ...以下略過
|
補充雷點
基本上發送郵件這邊有可能發生一個錯誤,就是被 Google 阻擋。
所以當出現錯誤的時候可以將紅框處複製下來組成一個網址,然後再登入發送郵件的帳號,在 URL 貼上你組好的字串即可,如果出現被出現重大訊息之類,就點進去信件內標註是我本人登入即可。
![這是一個組字串前奏]()
若沒問題的話基本上是可以發信哩~
![發信成功]()