flask爱家租房项目开发(十五--最后一班车)

本节代码(完整版)下载地址:https://download.csdn.net/download/geek_xiong/11622490

scrf_token缺失的解决办法

每次再登陆状态下点击退出,再登陆(不手动刷新页面)时会报缺失csrf_token的错误,如下图

根据图中的信息可以知道,退出再登陆,csrf_token是从session中获取的,但是当初我们并没有将scrf_token写入到session中,代码如下

# web_html.py

# 创建一个csrf_token的值
csrf_token = csrf.generate_csrf()

# flask 提供的返回静态文件的方法
resp = make_response(current_app.send_static_file(html_file_name))

# 设置cookie值
resp.set_cookie('csrf_token', csrf_token)

只是将scrf_token添加到了cookie中

那么,既然要从session中获取,我们设置session就可以了,还有必要设置cookie吗?

答案是肯定的,前端向后端发起请求时,是需要携带scrf_token提供验证的,而前端发起请求是会发送请求头、请求体的。即可以在cookie、headers、body中获取csrf_token。项目中用的是headers。

Request Headers

     POST /api/v1.0/sessions HTTP/1.1
     Host: 127.0.0.1:5000
     X-CSRFToken:       IjZmMmM0ZWE0NzZmZGQ0YjdkNzY2YWM0M2Y3NTkyODU4YzdlMTdkYTQi.XWUIRg.HP92hfiU83pEEUswE_kS5qar1b8
X-Requested-With: XMLHttpRequest
     Content-Type: application/json
     Origin: http://127.0.0.1:5000
     Referer: http://127.0.0.1:5000/login.html
     Cookie: csrf_token=IjZmMmM0ZWE0NzZmZGQ0YjdkNzY2YWM0M2Y3NTkyODU4YzdlMTdkYTQi.XWUIRg.HP92hfiU83pEEUswE_kS5qar1b8; session=da0e92c7-6448-48b8-8a66-a7107dd362eb.GauJNsu61mu3gDcP3zY1CZoiJwI

又有问题了,我们只设置了cookie,没有设置session啊!

答案其实是scrf自己设置的。因为我们在创建csrf_token值的时候调用的是flask下的scrf下的generate_csrf方法,而这个generate_csrf在生成csrf_token后自己添加到RedisSession(session)中了,代码如下:

# csrf.py

def generate_csrf(secret_key=None, token_key=None):
    """Generate a CSRF token. The token is cached for a request, so multiple
    calls to this function will generate the same token.

    During testing, it might be useful to access the signed token in
    ``g.csrf_token`` and the raw token in ``session['csrf_token']``.

    :param secret_key: Used to securely sign the token. Default is
        ``WTF_CSRF_SECRET_KEY`` or ``SECRET_KEY``.
    :param token_key: Key where token is stored in session for comparision.
        Default is ``WTF_CSRF_FIELD_NAME`` or ``'csrf_token'``.
    """

    secret_key = _get_config(
        secret_key, 'WTF_CSRF_SECRET_KEY', current_app.secret_key,
        message='A secret key is required to use CSRF.'
    )
    field_name = _get_config(
        token_key, 'WTF_CSRF_FIELD_NAME', 'csrf_token',
        message='A field name is required to use CSRF.'
    )

    if field_name not in g:
        if field_name not in session:
            session[field_name] = hashlib.sha1(os.urandom(64)).hexdigest()

        s = URLSafeTimedSerializer(secret_key, salt='wtf-csrf-token')
        setattr(g, field_name, s.dumps(session[field_name]))

    return g.get(field_name)

最后几行中可以看到 session[field_name] = xxx 就是添加csrf_token到session了

而我们项目点击退出时,后端只是清除了session数据,所以再次登录时就会session csrf_token缺失了。

解决办法:清空后,将csrf_token添加到session中

# passport.py

# 修改前
@api.route('/session', methods=['DELETE'])
def logout():
    """退出"""
    # 清除session数据
    session.clear()
    return jsonify(errno=RET.OK, errmsg='ok')


# 修改后
@api.route('/session', methods=['DELETE'])
def logout():
    """退出"""
    # 清除session数据
    csrf_token = session.get("csrf_token")
    session.clear()
    session['csrf_token'] = csrf_token
    return jsonify(errno=RET.OK, errmsg='ok')

测试

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秒不可闫M先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值