吃麻辣烫理解到的WEB会话技术

86 阅读5分钟

启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情

首先回顾一下HTTP协议的请求过程:

  • 客户端与服务端建立连接(TCP)
  • 客户端向服务端发起请求
  • 服务端接受请求,并根据请求参数返回响应内容
  • 客户端与服务端关闭连接

但是这里关注的是HTTP协议的另外一个特质,HTTP是无状态协议,这里的无状态是指HTTP服务端并不保留与客户交互时的任何状态(常指多个请求之间)也就是前后两次请求不会有相互之间的关联,这样就没法保证这次访问和下次访问的是同一个用户了,但是现在的网站都有一个登录功能,那么就需要有方案去保证两次请求都是一个用户,恰好今天想吃了麻辣烫,那么就以一碗麻辣烫来聊聊的WEB会话技术。

Cookie技术

原理

感觉饿了,去餐厅点了一份麻辣烫,走进餐厅,选了丸子,蟹棒,方便面等等,然后交给老板,老板称重,然后给了我一个小牌子,08号,那么之后我就可以到座位上玩手机了,直到老板大喝一声:8号麻辣烫好了,那么我就知道是我的麻辣烫好了,哎,仔细琢磨一下:

image-20221202181743944.png

那这种策略是不是可以使用在HTTP会话当中呢,嘿嘿嘿,个人感觉原理上是一致的。

用户提交用户名和密码到服务器,服务器下发一个校验的值,之后用户携带校验值去请求服务器,服务器以这个校验值来判断用户身份,这种策略叫做cookie(其实英文意思是曲奇)。

image-20221202182305296.png

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所有的所有参数

参数描述
keycookie的键
valuecookie的值
max_agecookie的寿命,和过期时间设置一个就可以了,过期失效
expirescookie过期时间,和寿命设置一个就可以了,过期失效
pathcookie生效的本站范围,默认是/,就是全栈生效
domain可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.”。
secure该Cookie是否仅被使用安全协议传输。安全协议。安全协议有HTTPS,SSL等,在网络上传输数据之前先将数据加密。默认为false。
httponlyHttpOnly是加在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),开头简陋,就是一个纸片,上面有金额,每次手动修改,但是随着会员卡变多了,出现了用户自己修改金额的事情,老板一咬牙,升级了会员卡,变成了磁卡,每次刷卡,用户不知道卡当中的信息,也不能自己修改,这样识别用户和保证安全都做到了。

image-20221202192311141.png

session技术也是这样的,session只会给用户下发一个session_id,当然这个session_id也是通过cookie下发的,用户请求服务器携带session_id,而具体的用户信息被保存在了服务器上,这样,就可以起到安全的作用了。

image-20221202192311141.png

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要结合使用。