expressWEB开发
# 身份认证
- 服务端渲染
Session
认证机制 - 前后端分离
JWT
认证机制
# session
# HTTP协议的无状态性
指的是客户端每次 HTTP 请求都是独立的,连续多次请求之间没有直接的关系,服务器不会保留每次 HTTP 请求的状态
意思是每次 HTTP 请求不在服务器保留状态,每次的请求都是独立的
# Session认证机制
为了突破 HTTP 无状态的限制
# Cookie
Cookie
是存储在用户浏览器中的一段不超过 4KB 的字符串 , 它由一个名称、一个值和其它几个用户控制 Cookie
有效期、安全性、使用范围的可选属性组成
每当客户端发起请求,会自动把当前域名下所有未过期的 Cookie
一同不送到服务器
- 自动发送
- 域名独立
- 过期时限
- 4KB 限制
身份认证作用
客户端第一次请求服务器时,服务器通过响应头形式向客户端发送一个Cookie,客户端会自动保存在浏览器中
随后当浏览器每次请求服务器的时候,浏览器会自动将身份认证相关的 Cookie ,通过请求头的形式发送给服务器,用于服务器的身份认证
Cookie不具有安全性,可伪造
可通过
# 工作原理
客户端首次发起请求,服务器将用户信息存储在服务器中,同时生成对应的Cookie
字符串
客户端再次发起请求时,通过请求头自动把可用的 Cookie
发送给服务器,服务器根据请求头中携带的Cookie
从内存中查找对应的用户信息
再根据当前用户生成特定的响应内容
# express-session
按照包 yarn add express-session
配置中间件
let session = require('express-session')
app.use(session({
secret:'key',
resave:false,
saveUninttiablized:true
}))
2
3
4
5
6
7
向session中存数据
app.post('/api/login',(req,res)=>{
if(req.body.username!=='admin'|| req.body.password!=='admin'){
return res.send({status:1,msg:'error login'})
}
req.session.user = req.body
req.session.islogin = true
res.send({status:0,msg:'success login'})
})
2
3
4
5
6
7
8
向session中取数据
app.get('/api/username',(req,res)=>{
if(!req.session.islogin){
return res.send({status:1,msg:'error '})
}
res.send({status:0,msg:'success',username:req.session.username})
})
2
3
4
5
6
清空session
app.post('/api/logout',(req,res)=>{
req.session.destory()
res.send({
status:0,
msg:'success'
})
})
2
3
4
5
6
7
# JWT
JWT
(JSON Web Token) 时目前流行的跨域认证解决方案
工作原理
客户端首次请求服务器,服务器会将用户的信息,经过加密之后生成 TOKEN
字符串,客户端会将 Token
存储到 本地 LocalStorage
或 SessionStorage
客户端再次发起请求时,通过请求头的 Authorization 字段,将Token
发送给服务器,服务器把 Token 字段还原为用户的信息对象
# 组成部分
Header
头部、 Payload
有效载荷 、 Signature
签名
三者之间使用 ,
分割
payload
是用户的信息部分,头部和签名是为了保证 Token
的安全性
# 使用
Authorization:Bearer <token>
安装相关包
yarn add jsonwebtoken express-jwt
const jwt = require('jsonwebtoken')
const expressJWT = require('exress-jwt')
2
3
jsonwebtoken
用于生成JWT
字符串express-jwt
用于将JWT
字符串解析还原为JSON
对象
定义 secret 密钥
为了保证 JWT 字符串的安全性,需要专门定义一个用于加密和解密的密钥
const secretKey = 'yuadh_web_key'
生成JWT字符串
调用jsonwebtoken
的 sign()
方法
const tokenStr = jwt.sign({username:usreinfo.username},secretKey,{expiresIn:'3s'})
- 参数1 : 需要加密的信息对象
- 参数2 : 加密的密钥
- 参数3 : 配置对象,
expireIn
过期时间
还原JWT
app.use(expressJWT({
secret:secretKey
}).unless({path:[/^\/api\//]}))
2
3
- unless用于指定哪些接口不需要访问权限
注意:
只要配置成功了 express-jwt
,会自动把解析出来的用户信息挂载到 req.user
属性上
# 失败捕获
app.use((err,req,res,next)=>{
if(err.name==='UnauthorizedError'){
return res.send({
status:401,
message:'无效token'
})
}
res.send({
status:500,
message:'未知其它错误'
})
})
2
3
4
5
6
7
8
9
10
11
12