Session产生的原因:
在了解学习过浏览器访问服务器的过程的应该了解,浏览器这样的客户端在访问服务端的时候,是通过http协议进行通信的;但是这个http协议有这样的一个情况,就是无状态的;什么是无状态的,就是在这一次发出请求的时候,并不知道同一用户在之前有没有发生过请求。例如如下的对话:
案例①
A:你学过python吗?
B:学过。
A:那你学的怎么样?
B:啊,学的怎么样,什么怎么样?
案例②:
A:你学过python吗?
B:学过。
A:你学过python吗?
B:学过。
现在将A比作浏览器,B比作服务器;
案例①的情况,就是浏览器对请求有记忆,在第一次询问过后,知道服务器学过python,所以会进行下一个与上一个话题相关的问题进行进一步的询问;但是服务器是无状态的,所以在之前发生过什么事情,它都是没有记录的,所以不知道第二次请求的时候,浏览器问的是什么鬼;
案例②的情况就是,浏览器和服务器都是无状态的,在浏览器进行第一次询问,得到服务器的结果后,由于都是无状态的,所以会把同一个问题再次询问。
而我们浏览器和服务器的通信过程就是类似于案例②中的,两个都是无状态的过程;但是这样的无状态过程,在实际应用中是非常不方便的,比如我们在登陆了csdn博客网站的时候,我们正在写文章,在你准备发布的时候,由于无状态的原因,你在发布时还需要重新进行登陆,这样的情况在用户体验和数据绑定方面会大大折扣。
这样一来,状态保持这个机制就得需要出来帮忙了,状态保持目前有两种方式:
- 在客户端存储信息:cookie
- 在服务器存储信息:session
cookie交互过程解析链接:
https://blog.csdn.net/gymaisyl/article/details/83065869
Cookie:cookie是把信息保存在用户浏览器本地的,它在一个域名下是一个全局的,也就是在同一个域名下才可以进行访问;所以就很好的解决了在同一个网站页面登陆的问题,可以在同一个网站获取到这个登陆信息了,同时又不用反复去查询数据库。
虽然这种方案很不错,也很快速方便,但是由于cookie 是存在用户端,而且它本身存储的尺寸大小也有限,最关键是用户可以是可见的,并可以随意的修改,很不安全。那如何又要安全,又可以方便的全局读取信息呢?于是,session就出现了。
- 对于敏感、重要的信息,建议要存储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息
- 在服务器端进行状态保持的方案就是Session
- Session依赖于Cookie
Session的交互过程是如何的呢?
我们就以用户登陆某个网站这作为案例:(假设是第一次登陆)
1.浏览器向服务器发送登陆的请求,此时在请求时,将用户名和密码也放在请求报文中,发给服务器:
# 用户名和密码:
'user_name' = 'daxiong'
'user_pwd' = '123456'
2.服务器收到浏览器的请求,将收到的用户名和密码与数据库的的用户信息进行匹配,匹配成功的话,会返回登陆成功的响应内容给浏览器;但是与此同时,服务器会生成一个session:
# 用户信息
session['user_name'] = 'daxiong'
session['user_pwd'] = '123456'
当然,这个session被设置生成之前,会调用session_start()这个函数开启session; 这是个无任何返回值的函数,既不会报错,也不会成功。它的作用是开启session,并随机生成一个唯一的32位的session_id,类似于这样:drehirefvjebvhebvef;
此时,在服务器里面,会有一个独一无二的session_id对应上段代码中的用户信息:
session_id —>{session[‘user_name’] = ‘daxiong’,
session[‘user_pwd’] = ‘123456’}
将要保存的session数据与session_id对应,保存到session服务器(数据库 , redis , 程序全局变量中)中
3.服务器需要将用户登陆成功的数据响应给浏览器,当然,与此同时,服务器会把刚才生成的session_id也放在响应报文中,返回给浏览器;
之前提及过,session是依赖于cookie的;它依赖的就是在服务器将响应报文返回给浏览器这个过程,这个过程是通过cookie的机制进行完成的;也就是说,服务器会把session_id存放在cookie中,发给浏览器,我们在浏览器中查询时,也是通过在cookie中查询到session的。
session中对应的内容是一段乱码,是因为我们在生成内容是,是需要进行加密的:
# 机密处理 - 参考代码
app.config['SECRET_KEY'] = 'qwertyikjhgfds'
加密的主作用:是在其加密过程中作为算法(HASH)的一个参数,可在 Flask 和多个第三方扩展中使用. 加密的强度取决于变量值的机密度. 不同的程序要使用不同的密钥, 而且要保证其他人不知道你所用的字符串.
4.浏览器接收到服务器响应报文中的cookie,把cookie里面的session_id保存,并在下一次请求服务器时,把这个cookie(包含session_id)存放在请求报文中,发给服务器。
5.服务器收到浏览器的再次请求报文,服务器会去读取这个请求报文中的cookie是否有值,是否过期;如果读取到对应的session_id,则会继续使用;如果不存在或者过期了,就需要再生成一个session_id,当然,这个时候就需要用户再一次进行登陆操作了。
注意(拓展):
由于session是依赖于cookie,嵌套在cookie中使用的,如果cookie被关闭,就需要加在url后面,完成session_id的传递