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可以獲取用戶信息。