Contents
接上一篇文章《node.js Express 创建RESTful API》
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:123456@localhost: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.' }); } });4458