推荐先阅读:
Jothy:Server端的认证神器——JWT(一)zhuanlan.zhihu.com
JSON Web Token 入门教程www.ruanyifeng.com
node实现简易的jwt认证
目录结构:

// user.js
const mongoose = require('mongoose')
const {Schema} = mongoose
const userSchema = new Schema({
name: String,
password: String,
admin: Boolean
})
module.exports = mongoose.model('User', userSchema)// config.js
module.exports = {
'secret': 'ilovescotchyscotch', // 密钥
'db': 'mongodb://localhost:/test'
}// package.json
{
"name": "token-jwt",
"version": "1.0.0",
"description": "node jwt",
"main": "server.js",
"scripts": {
"start": "nodemon server.js"
},
"keywords": [
"jwt"
],
"author": "xyz",
"license": "ISC",
"dependencies": {
"express": "^4.16.4",
"jsonwebtoken": "^8.4.0",
"mongoose": "^5.3.13",
"morgan": "^1.9.1"
},
"devDependencies": {
"nodemon": "^1.18.6"
}
}// server.js
const Express = require('express')
const mongoose = require('mongoose')
const logger = require('morgan')
const jwt = require('jsonwebtoken')
const config = require('./config.js')
const User = require('./app/models/user.js')
const app = Express()
const PORT = process.env.PORT || 3000
const apiRoutes = Express.Router()
mongoose.connect(config.db, { useNewUrlParser: true })
app.set('superSecret', config.secret) // 设置secret
app.use(logger('dev'))
app.use(Express.json())
app.use(Express.urlencoded({ extended: false }))
app.get('/', function (req, res) {
res.send(`api地址: localhost:3000/api`)
})
// 创建用户
app.post('/register', function (req, res) {
console.log(req.body)
const { name = '', password = '', admin = false} = req.body
const requiredField = {
name,
password
}
let isPass = true
for (let key in requiredField) {
if (requiredField[key] === '' && isPass) {
isPass = false
res.json({
msg: `${key}不能为空`
})
}
}
if (!isPass) { return }
User.findOne({name}, function (err, user) {
if (err) {
res.send(err)
return
}
if (!user) {
const user = new User({
name,
password, // 实际项目不会存明文
admin
})
user.save(function (err, user) {
if (err) {
res.send(err)
}
res.json({
msg: '创建成功'
})
})
} else {
res.json({
msg: '已存在同名用户'
})
}
})
})
// 生成token
app.get('/login', function (req, res) {
console.log(req.query)
const { name = '', password = ''} = req.query
const requiredField = {
name,
password
}
let isPass = true
for (let key in requiredField) {
if (requiredField[key] === '' && isPass) {
isPass = false
res.json({
msg: `${key}不能为空`
})
}
}
if (!isPass) { return }
User.findOne({name, password}, function (err, user) {
if (err) {
res.send(err)
return
}
if (!user) {
res.json({
msg: '用户名或者密码错误'
})
} else {
const payload = {
admin: user.admin
}
const token = jwt.sign(payload, app.get('superSecret'), {
expiresIn: 1440
})
res.json({
success: true,
data: user,
token
})
}
})
})
// token校验中间件
apiRoutes.use(function (req, res, next) {
const token = req.body.token || req.query.token || req.headers['x-access-token']
if (token) {
jwt.verify(token, app.get('superSecret'), function (err, decoded) {
if (err) {
return res.json({ success: false, message: 'Failed to authenticate token.' })
} else {
req.decoded = decoded
next()
}
})
} else {
return res.status(403).send({
success: false,
msg: '需要token令牌'
})
}
})
apiRoutes.get('/users', function (req, res) {
User.find({}, function (err, users) {
if (err) {
res.send(err)
}
res.json({
data: users
})
})
})
apiRoutes.get('/', function (req, res) {
res.json({
msg: '这里面的路由需要token验证。'
})
})
app.use('/api', apiRoutes)
app.listen(PORT)
console.log(`server is on the port: ${PORT}`)使用postman测试所有接口。