启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
首先回顾一下HTTP协议的请求过程:
- 客户端与服务端建立连接(TCP)
- 客户端向服务端发起请求
- 服务端接受请求,并根据请求参数返回响应内容
- 客户端与服务端关闭连接
但是这里关注的是HTTP协议的另外一个特质,HTTP是无状态协议,这里的无状态是指HTTP服务端并不保留与客户交互时的任何状态(常指多个请求之间)也就是前后两次请求不会有相互之间的关联,这样就没法保证这次访问和下次访问的是同一个用户了,但是现在的网站都有一个登录功能,那么就需要有方案去保证两次请求都是一个用户,恰好今天想吃了麻辣烫,那么就以一碗麻辣烫来聊聊的WEB会话技术。
Cookie技术
原理
感觉饿了,去餐厅点了一份麻辣烫,走进餐厅,选了丸子,蟹棒,方便面等等,然后交给老板,老板称重,然后给了我一个小牌子,08号,那么之后我就可以到座位上玩手机了,直到老板大喝一声:8号麻辣烫好了,那么我就知道是我的麻辣烫好了,哎,仔细琢磨一下:
那这种策略是不是可以使用在HTTP会话当中呢,嘿嘿嘿,个人感觉原理上是一致的。
用户提交用户名和密码到服务器,服务器下发一个校验的值,之后用户携带校验值去请求服务器,服务器以这个校验值来判断用户身份,这种策略叫做cookie(其实英文意思是曲奇)。
Flask实现
flask 作为一个成熟的web框架,自然也提供了cookie技术,可以通过响应对象对cookie进行设置,基本的操作逻辑:
设置cookie
cookie是需要下发给用户的,所以需要在response上设置在cookie。
@app.route("/login")
def login():
response = make_response({"name": "hello world"})
response.set_cookie("username","admin")
return response
为了更好的掌握cookie原理,这里列出设置cookie所有的所有参数
| 参数 | 描述 |
|---|---|
| key | cookie的键 |
| value | cookie的值 |
| max_age | cookie的寿命,和过期时间设置一个就可以了,过期失效 |
| expires | cookie过期时间,和寿命设置一个就可以了,过期失效 |
| path | cookie生效的本站范围,默认是/,就是全栈生效 |
| domain | 可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.”。 |
| secure | 该Cookie是否仅被使用安全协议传输。安全协议。安全协议有HTTPS,SSL等,在网络上传输数据之前先将数据加密。默认为false。 |
| httponly | HttpOnly是加在cookies上的一个标识,用于告诉浏览器不要向客户端脚本(document.cookie或其他)暴露cookie。 |
| samesite | 禁用第三方携带Cookie。导致链接跳转或者接口请求第三方都无法携带Cookie,用来防止CSRF攻击。 |
获取cookie
cookie是用户提交的,所以获取cookie是需要从请求部分获取。
@app.route("/index")
def index():
username = request.cookies.get("username") #获取cookie
if username:
return render_template("index.html")
return redirect("/login")
删除cookie
当然如果触发类似退出功能,cookie也需要删除,所以,需要在响应上进行删除
@app.route("/logout")
def logout():
response = make_response({"name": "hello world"}) #删除cookie
response.delete_cookie("username")
return response
Session技术
cookie技术已经实现了用户身份的校验,但是还是有很大的缺陷,因为cookie是从服务器下发到用户本地保存的,所以容易被盗取,模仿和修改。所以基于cookie技术又拓展出了session技术。
还是那麻辣烫说事儿吧,经常吃,所以老板决定和我商量办会员卡(充200,送50),开头简陋,就是一个纸片,上面有金额,每次手动修改,但是随着会员卡变多了,出现了用户自己修改金额的事情,老板一咬牙,升级了会员卡,变成了磁卡,每次刷卡,用户不知道卡当中的信息,也不能自己修改,这样识别用户和保证安全都做到了。
session技术也是这样的,session只会给用户下发一个session_id,当然这个session_id也是通过cookie下发的,用户请求服务器携带session_id,而具体的用户信息被保存在了服务器上,这样,就可以起到安全的作用了。
Flask同样支持session,但是要注意的是:flask的session是通过加密后保存在cookie中的,有加密就需要有解密用的密钥,所以只要用到了flask的session模块,就一定要配置’SECRET_KEY’这个全局配置。
具体session操作,由于session在flask当中是一个类字典对象,所以,可以使用字典的方式进行操作:
配置session盐值
from flask import Flask, request,redirect,session
from flask import make_response,render_template
app = Flask(__name__)
app.config["SESSION_KEY"] = "hello world"
.....
设置session
@app.route("/login")
def login():
session['username'] = 'admin' #设置session
response = make_response({"name": "admin"})
return response
获取session
@app.route("/index")
def index():
username = session.get('username')
#username = session['username']
if username:
return render_template("index.html")
return redirect("/login")
删除session
@app.route("/logout")
def logout():
session.pop("username") #弹出session
session.clear() #删除session
response = make_response({"name": "logout"})
return response
这里要注意的是,session也是有一个很明显的缺点的,就是需要保存在服务器上,校验需要通过服务器,容易增大服务器的压力,所以cookie和session要结合使用。