会话控制

更新时间: 2024-11-18 10:54:38

# 会话控制介绍

所谓会话控制就是对会话进行控制,HTTP是一种无状态的协议,它没有办法区分不多的请求是否来自同一个客户端,无法区分用户
而产品中又大量存在这样的需求,所以我们需要通过会话控制来解决该问题

常见的会话控制技术有三种:

  • cookie
  • session
  • token

# cookie的介绍

  • cookie是什么
    cookie是HTTP服务器发送到用户浏览器并保存在本地的一小块数据
    cookie是保存在浏览器端的一小块数据
    cookie是按照域名划分保存的

简单示例:

域名 cookie
www.baidu.com a=100;b=200
www.bilibili.com xid=120abce121;hm=112411213
js.com x=100;ocw=12414cce
  • cookie的特点
    浏览器向服务器发送请求时,会自动将当前域名下可用的cookie设置在请求头中,然后传递给服务器,这个请求头的名字也叫cookie,所以将cookie理解为一个HTTP的请求头也是可以的

  • cookie的运行流程
    填写账号和密码校验身份,校验通过后下发cookie
    有了cookie之后,后续向服务器发送请求时,就会自动携带cookie

# 浏览器操作cookie

浏览器操作cookie的操作,使用相对较少,大家了解即可

  1. 禁用所有cookie
  2. 删除cookie
  3. 查看cookie 不同浏览器cookie不共享

# express框架中设置cookie

// 导入 express  
const express = require('express')  

// 创建应用对象  
const app = express()  
 
// 创建路由规则  
app.get('/set-cookie', (req, res) => {
    res.cookie('name','zhangsan') //  会在浏览器关闭的时候销毁  
    res.cookie('age','99',{maxAge: 60 * 1000}) // 1分钟销毁  
    res.send('home')
})

// 启动服务  
app.listen(3000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# express框架中删除cookie

// 删除 cookie
app.get('/remove-cookie', (req, res) => {
    // 调用方法
    res.clearCookie('name')
    res.send('删除成功')
})
1
2
3
4
5
6

# express框架中获取cookie

 express = require('express')  
// 导入cookie-parser,需要先安装    
const cookieParser = require('cookie-parser')  

// 创建应用对象  
const app = express()  
app.use(cookieParser())

//....

// 获取cookie  
app.get('/get-cookie',(req, res) => {
    console.log(req.cookies)
    res.send('获取 cookie')
})

// 启动服务  
app.listen(3000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# session的介绍

  • session是什么
    session是保存在服务器端的一块数据,保存当前访问用户的相关信息

  • session的作用
    实现会话控制,可以识别用户的身份,快速获取当前用户的相关信息

  • session运行流程
    填写账号和密码校验身份,校验通过后创建session信息,然后将session_id的值通过响应头返回给浏览器
    有了cookie,下次发送请求时会自动携带cookie,服务器通过cookie中的session_id的值确定用户的身份

# express-session安装与配置

express中可以使用express-session对session进行操作

const express = require('express')  
// 1. 安装包  npm i express-session connect-mongo  
// 2. 引入 express-session connect-mongo  
const session = require('express-session')  
const MongoStore = require('connect-mongo')  

const app = express()

app.use(session({
    name: 'sid',
    secret: 'atguigu',
    saveUninitialized: false,
    resave: true,
    store: MongoStore.create({
        mongoUrl: 'mongodb://127.0.0.1:27017/project'
    }),
    cookie: {
        httpOnly: true,
        maxAge: 1000 * 300
    }
}))

// 登录
app.get('/login', (req, res) => {
    if(req.query.username === 'admin' && req.query.password === 'admin') {
        // 设置session信息  
        req.session.username = 'admin'
        req.session.uid = '258aefccc'
        // 成功响应
        res.send('登录成功')
    }else{
        res.send('登录失败')
    }
})

// session的读取
app.get('/cart',(req, res) => {
    // 检测session是否存在用户数据  
    if(req.session.username) {
        res.send(`购物车页面,欢迎您${req.session.username}`)
    }else{
        res.send('您还没有登录~~')
    }
})

// session的销毁
app.get('/logout',(req, res) => {
    req.session.destroy(() => {
        res.send('退出成功')
    })
})

app.listen(3000, () => {
    console.log('服务已经启动')
})
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

# session与cookie的区别

cookie和session的区别主要有如下几点:

  1. 存在的位置
  • cookie: 浏览器端
  • session: 服务端
  1. 安全性
  • cookie是以明文的方式存放在客户端的,安全性相对较低
  • session存放于服务器中,所以安全性相对较好
  1. 网络传输量
  • cookie设置内容多会增大报文体积,会影响传输效率
  • session数据存储在服务器,只是通过cookie传递id,所以不影响传输效率
  1. 存储限制
  • 浏览器限制单个cookie保存的数据不能超过4K,且单个域名下的存储数量也有限制
  • session数据存储在服务器中,所以没有这些限制

# token的介绍

  • token是什么
    token是服务端生成并返回给HTTP客户端的一串加密字符串,token中保存着用户信息

  • token的作用
    实现会话控制,可以识别用户的身份,主要用于移动端APP

  • token的工作流程
    填写账号和密码校验身份,校验通过后响应token,token一般是在响应体中返回给客户端的
    后续发送请求时,需要手动将token添加在请求报文中,一般是放在请求头中

  • token的特点

  1. 服务端压力更小

    • 数据存储在客户端
  2. 相对更安全

    • 数据加密
    • 可以避免CSRF(跨站请求伪造)
  3. 扩展性更强

    • 服务间可以共享
    • 增加服务节点更简单

# JWT介绍与演示

JWT(JSON Web Token)是目前最流行的跨域认证解决方案,可用于基于token的身份验证

JWT使token的生成与校验更规范

我们可以使用jsonwebtoken包来操作token

// 导入 jsonwebtoken  
const jwt = require('jsonwebtoken')

// 创建token 
// jwt.sign(数据,加密字符串,配置对象) 
let token = jwt.sign({
    username: 'zhangsan'
},'atguigu',{
    expiresIn: 60 // 单位是秒
})

// 解析token
jwt.verify(token, 'atguigu', (err, data) => {
    if(err) {
        console.log('校验失败~~~')
        return 
    }
    console.log(data)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19