node.js Express RESTful API 認證
阿新 • • 發佈:2019-01-10
1.安裝依賴node-token-jwt,morgan
npm install jsonwebtoken morgan --save
jsonwebtoken 用來建立和驗證json token
2. 專案結構
增加了一個user model,一個setup 用來建立一個測試使用者,config裡記錄一個key用來給jsonwebtoken來建立token
2.1 config.js
module.exports = { 'secret': 'testnodejs', 'database': 'mongodb://article:[email protected]:27017/xiaohua1' };
3. user.js
// get an instance of mongoose and mongoose.Schema var mongoose = require('mongoose'); var Schema = mongoose.Schema; // set up a mongoose model and pass it using module.exports module.exports = mongoose.model('User', new Schema({ name: String, password: String, admin: Boolean }));
4. Setup.js
app.js 中加setup路由
var setupRouter = require('./routes/setup')
app.use('/setup', setupRouter)
setup.js
var express = require('express'); var router = express.Router(); var User = require('../models/user') /* GET home page. */ router.get('/', function(req, res, next) { var nick = new User({ name: 'test', password: 'password', admin: true }); // save the sample user nick.save(function(err) { if (err) throw err; console.log('User saved successfully'); res.json({ success: true }); }); }); module.exports = router;
訪問:http://127.0.0.1:3000/setup 就可以在資料庫中建立測試使用者了,3000是我這邊的埠。
這邊密碼是明文的,後續還要修改下。
5. authenticate,生成token
api.js
var User = require('../models/user')
var jwt = require('jsonwebtoken');
var config = require('../config');
// route to authenticate a user (POST http://localhost:3000/api/authenticate)
router.route('/authenticate')
.post( function(req, res) {
// find the user
User.findOne({
name: req.body.name
}, function(err, user) {
if (err) throw err;
if (!user) {
res.json({ success: false, message: 'Authentication failed. User not found.' });
} else if (user) {
// check if password matches
if (user.password != req.body.password) {
res.json({ success: false, message: 'Authentication failed. Wrong password.' });
} else {
// if user is found and password is right
// create a token with only our given payload
// we don't want to pass in the entire user since that has the password
const payload = {
admin: user.admin
};
var token = jwt.sign(payload, config.secret, {
expiresIn: 1440 // expires in 1440 seconds
});
// return the information including token as JSON
res.json({
success: true,
message: 'Enjoy your token!',
token: token
});
}
}
});
});
用postman測試下,就可以得到token
6.驗證
// middleware to use for all requests
router.use(function(req, res, next) {
// do logging
// console.log('Something is happening.');
// next(); // make sure we go to the next routes and don't stop here
// check header or url parameters or post parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, config.secret, function(err, decoded) {
if (err) {
return res.json({ success: false, message: 'Failed to authenticate token.' });
} else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
next();
}
});
} else {
// if there is no token
// return an error
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
});
把這個放在需要驗證的之前,因為判斷過了才會呼叫next()
加上token就可以了: