JWT
全称JSON Web Token,用于鉴权,体现为登录后存储用户信息
这是一段生成的token(令牌):
1
| eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWF0IjoxNjg3Njc0NDkyLCJleHAiOjE2ODc3NjA4OTJ9.Y6eFGv4KXqUhlRHglGCESvcJEnyMkMwM1WfICt8xYC4
|
JWT由三部分组成:头部、负载、签名
头部 (Header):通常由令牌的类型和所使用的签名算法两部分组成,通常采用JSON对象表示,并进行Base64 URL编码
1 2 3 4
| { "alg": "HS256", "typ": "JWT" }
|
- alg:所使用的签名算法,例如HMAC、SMA256 (HS256)、RSA等
- typ:令牌的类型,一般为JWT
负载 (Payload):包含所要传输的信息,例如用户的身份、权限等,也是一个JSON对象,同样进行Base64 URL编码
1 2 3 4 5 6
| { "iss": "example.com", "exp": 1624645200, "sub": "1234567890", "username": "johndoe" }
|
- iss:令牌颁发者 (Issuer),该JWT的签发者
- exp:过期时间 (Expiration Time),该JWT的过期时间,以Unix时间戳表示
- sub:主题 (Subject),该JWT所面向的用户,一般是用户的唯一标识
- 自定义声明:可以添加除了预定义声明之外的任意其他声明
签名 (Signature):使用私钥对头部和负载进行加密的结果,用于验证令牌的完整性和真实性
1 2 3 4 5
| HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secretKey )
|
express jwt
后端
安装依赖:
1
| npm i @types/express express cors jsonwebtoken
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| import express from 'express' import jwt from 'jsonwebtoken' import cors from 'cors'
let app = express()
app.use(express.json()) app.use(express.urlencoded({ extended: false }))
app.use(cors())
let Key = 'yjsp'
let user = { name: 'yajue', password: 114514, id: 1919810 }
app.post('/api/login', (req, res) => { if (req.body.name === user.name && req.body.password === user.password) { res.json({ message: '登录成功', token: jwt.sign({ id: user.id }, Key, { expiresIn: '1h' }) }) } else { res.status(403).json({ message: '用户名或密码错误' }) } })
app.get('/api/list', (req, res) => { const token = req.headers.authorization if (!token) { res.status(403).json({ message: '无权限' }) } else { const token2 = token.split(' ')[1] jwt.verify(token2, Key, (err, decode) => { if (err) { res.status(403).json({ message: '无权限' }) } else { res.json({ list: [ { id: 1, name: 'aaa' }, { id: 2, name: 'bbb' }, { id: 3, name: 'ccc' }, { id: 4, name: 'ddd' }, { id: 5, name: 'eee' } ] }) } }) } })
app.listen(3000, () => { console.log('server started') })
|
前端
index.html:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head>
<body> <div> <div> <span>账号</span><input id="name" type="text"> </div> <div> <span>账号</span><input id="password" type="password"> </div> <button id="btn"></button> </div> <script> const btn = document.getElementById('btn') const name = document.getElementById('name') const password = document.getElementById('password')
btn.onclick = ()=> { fetch('http://localhost:3000/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: name.value, password: password.value }) }).then(res=> res.json()).then(res=> { console.log(res) localStorage.setItem('token', res.token) location.href = './list.html' }) } </script> </body> </html>
|
list.html:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> fetch('http://localhost:3000/api/list', { headers: { 'Authorization': `Bearer ${localStorage.getItem("token")}` } }).then(res=> res.json()).then(res=> { console.log(res) }) </script> </body> </html>
|