const express = require('express')
const jwt = require('express-jwt')
const jwtSign = require('jsonwebtoken')
const cookieParser = require('cookie-parser')
const getCookieExpires = () => {
const d = new Date()
d.setTime(d.getTime() + (24 * 60 * 60 * 1000))
return d.toGMTString()
}
const JWT_PRIVATE_KEY = '123_test'
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(cookieParser())
// JWT默认会从req.header.authorization获取token,所以客户端请求中需要设置header的Authorization字段。
// 这个默认行为也可以通过getToken方法改变,比如从cookie中获取token
app.use(jwt({
secret: JWT_PRIVATE_KEY,
credentialsRequired: true,
getToken: (req) => req.cookies.mt_token,
}).unless({
path: [
'/',
'/user/login'
]
}))
app.get('/', (req, res) => {
res.end('home')
})
// 使用JWT生成的token有个弊端:
// 1.第一次登录的时候,如果使用const token1 = jwtSign.sign(
// {
// username,
// },
// JWT_PRIVATE_KEY,
// { expiresIn: 30 * 60 }
// )生成token1,token1里只有username信息,这时候cookie中存的是token1
// 2.如果由于需求变更,需要token里面再加入password,role等信息,即const token2 = jwtSign.sign(
// {
// username,
// role: 'admin',
// password
// },
// JWT_PRIVATE_KEY,
// { expiresIn: 30 * 60 }
// ),这时候cookie中依然是token1,需要用户重新登录才能生成token2,并存到cookie中。
// 所以如果不重新登录,则token中依然还是只有username这个信息,没有password和role信息。
// 如果使用session就没有这个问题。
// 而且使用jwt生成的token,做不了单点登录。如果需要做单点登录,就需要引入redis做状态管理
app.get('/user/login', (req, res) => {
const { username, password } = req.query
if(username === 'test' && password === '123456'){
const token = jwtSign.sign(
{
username,
role: 'admin',
password
},
JWT_PRIVATE_KEY,
{ expiresIn: 30 * 60 }
)
res.setHeader('Set-Cookie', `mt_token=${token};path=/;httpOnly;expires=${getCookieExpires()}`)
res.json({
code: 0,
msg: '登录成功',
token
})
} else {
res.json({
code: -1,
msg: '用户名或密码不正确'
})
}
})
app.get('/user/info', (req, res) => {
res.json(req.user)
})
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
res.status(401).send('invalid token...');
} else {
res.send('error')
}
});
const server = app.listen(9002, () => {
const { address, port } = server.address()
console.log('HTTP服务启动成功: http://%s:%s', address, port)
})
1.访问http://localhost:9002/user/login?username=test&password=123456模拟登录,当用户名和密码正确时,生成token并设置cookie。使用jwt生成的token,可以用express-jwt解析token里面的信息。解析后的信息存放在req.user中
2.访问http://localhost:9002/user/info可以获取用户信息。