Flask前后端分离之Flask_jwt_extended的使用(一)
本文最后更新于 422 天前,其中的信息可能已经有所发展或是发生改变。

JWT是一种用于身份验证和授权的安全传输方式,全称为JSON Web Token。

JSON Web Token (JWT)由三个部分组成:Header,Payload和Signature。

  • Header部分指定JWT使用的签名算法,例如HMAC SHA256或RSA。
  • Payload部分包含与身份验证和授权相关的信息,例如用户ID和访问权限等。
  • Signature部分通过使用Header和Payload部分的内容以及密钥来生成签名。用于验证JWT是否被篡改。

JWT的工作流程如下:

  1. 用户通过用户名和密码进行身份验证,身份验证成功后,服务器生成JWT。
  2. 服务器将JWT返回给客户端,客户端将JWT存储在本地。
  3. 客户端在每个请求中使用JWT作为身份验证凭证,服务器从JWT中验证用户的身份和访问权限。

JWT的优点是:

  1. 跨平台:JWT是基于JSON的标准,因此可以轻松地在不同平台之间传输。
  2. 安全:JWT的签名可以防止JWT在传输过程中被篡改。
  3. 无状态:服务器不需要在自己的存储中保存JWT,使得JWT非常适合在无状态的REST API中使用。

关于JWT的详细说明大家可以去看这个视频 https://www.bilibili.com/video/BV1ob4y1Y7Ep/

1、安装Flask-JWT-Extended库

pip install flask-jwt-extended

2、基本使用

flask_jwt_extended库用的最多的几个方法:

  • create_access_token() 用来创建 Token 令牌
  • create_refresh_toke() 用来创建刷新 Token的令牌
  • get_jwt_identity() 用来根据令牌取得之前的 identity 信息
  • jwt_required()这是一个装饰器,用来保护 flask 节点

2.1、导入使用

from flask_jwt_extended import JWTManager
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity

2.1、初始化

import datetime
from flask_jwt_extended import JWTManager
from flask import Flask

app = Flask(__name__)

app.config['SECRET_KEY'] = 'super-secret'  # 设置秘钥
# 配置JWT

app.config['JWT_SECRET_KEY'] = 'super-secret'  # 设置JWT秘钥
app.config['JWT_TOKEN_LOCATION'] = ['headers', 'cookies']  # 设置token的位置
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = datetime.timedelta(days=7)  # 设置access_token过期时间
app.config['JWT_REFRESH_TOKEN_EXPIRES'] = datetime.timedelta(days=1)  # 设置refresh_token过期时间
app.config['JWT_COOKIE_SECURE'] = True  # 设置cookie只能通过https传输
app.config['JWT_ACCESS_COOKIE_PATH'] = '/'  # 设置access_token的cookie路径
app.config['JWT_REFRESH_COOKIE_PATH'] = '/refresh'  # 设置refresh_token的cookie路径

# 初始化jwt
jwt = JWTManager(app)

2.2、flask_jwt_extended配置说明

JWT_TOKEN_LOCATION = ['cookies']
# ["headers", "cookies", "json", "query_string"]
# 指定JWT令牌在哪个位置进行身份验证。在这里,令牌存储在cookie中
JWT_COOKIE_SECURE = True
# 指定JWT cookie是否需要安全的HTTPS协议传输
JWT_ACCESS_COOKIE_PATH = '/'
JWT_REFRESH_COOKIE_PATH = '/refresh'
# 分别指定JWT访问令牌和刷新令牌的cookie路径
JWT_CSRF_IN_COOKIES = True
JWT_COOKIE_CSRF_PROTECT = True
# 启用JWT的CSRF保护。前者指定JWT的CSRF令牌是否存储在cookie中,后者指定是否需要验证来自客户端的CSRF令牌
JWT_ACCESS_CSRF_HEADER_NAME = 'X-CSRF-TOKEN-ACCESS'
JWT_REFRESH_CSRF_HEADER_NAME = 'X-CSRF-TOKEN-REFRESH'
# 指定JWT访问令牌和刷新令牌的CSRF请求头名称
JWT_ACCESS_CSRF_COOKIE_NAME = 'csrf_access_token'
JWT_REFRESH_CSRF_COOKIE_NAME = 'csrf_refresh_token'
# 指定JWT访问令牌和刷新令牌的CSRF cookie名称
JWT_ACCESS_TOKEN_EXPIRES = datetime.timedelta(days=7)
JWT_REFRESH_TOKEN_EXPIRES = datetime.timedelta(days=1)
# 分别指定JWT访问令牌和刷新令牌的过期时间。在这里,访问令牌的过期时间是7天,刷新令牌的过期时间是1天

2.3、登陆成功后生成JWT

这里我用的json来获取到请求中的用户名和密码,如果登陆成功后,会把token返回给前端。

@app.route('/login', methods=['POST'])
def login():
    # 从请求的json数据中获取用户名和密码
    username = request.json.get('username', None)
    password = request.json.get('password', None)
    # 验证用户名和密码是否正确
    if username != 'admin' or password != '123456':
        return jsonify({'code': 401, 'msg': '用户名或密码错误'})
    else:
        # 生成access_token
        access_token = create_access_token(identity=username)
        # 将生成的token返回给前端
        response = jsonify({'code': 200, 'msg': '登录成功', 'access_token': access_token})
        return response

我们使用Apifox来测试一下我们刚刚的示例。成功拿到这里的JWT了。

1682530210052.png

2.4、jwt_required装饰器的使用

jwt_required主要是对接口进行鉴权,@jwt_required(locations=['headers', 'cookies']) 是 Flask-JWT-Extended 扩展提供的装饰器,用于保护需要身份验证的端点(endpoint)。它除了检查请求的 Authorization 头是否包含有效的 JSON Web Token(JWT),还会检查请求中 cookies 中是否包含有效的 JWT Token。

@app.route('/test', methods=['POST'])
@jwt_required(locations=['headers', 'cookies'])
def test():
    # 获取当前token的身份信息
    current_identity = get_jwt_identity()
    # 判断当前token是否存在
    if current_identity:
        # 返回当前token的身份信息
        return jsonify({'code': 200, 'msg': '请求成功', 'current_identity': current_identity})
    else:
        # 返回错误信息
        return jsonify({'code': 401, 'msg': '请先登录认证'})

我们使用Apifox分别来测试一下没有在请求中携带token和携带了token的效果。这样能够直观的体现出jwt_required的作用.

2.4.1、未携带JWT

这句话的意思是说:缺少 JWT(JSON Web Token)在请求头或者 Cookie 中(缺少授权头;缺少名为“access_token_cookie”的 Cookie)。也就是我们要在headerCookie中携带 JWT.

1682530876972.png

2.4.2、请求头携带JWT

我们要设置请求header 标头来验证请求(Bearer Token),就是我们获取的JWT,例如:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY4MjUzMDE4MiwianRpIjoiOGUyM2U0M2MtZTVjYy00ZjE1LTk1MzYtZDgyNWJiN2EzNTE2IiwidHlwZSI6ImFjY2VzcyIsInN1YiI6ImFkbWluIiwibmJmIjoxNjgyNTMwMTgyLCJjc3JmIjoiMzY2MDMxZTMtYzMzYS00MzQwLTliMjAtYTFkNDc0ZjI3Y2FhIiwiZXhwIjoxNjgzMTM0OTgyfQ.qIaJuTj471pcmitm_Ff6B6h9NPZXZo6iNAbtFXK8n1A

下面这个示例,我们在请求header标头添加了上面的参数就可以验证成功了

1682531364364.png

3、完整代码

#!/usr/bin/env python3 
# -*- coding: utf-8 -*-
# @Time    : 2023/4/27 0:55
# @Author  : Small tred
# @FileName: app.py.py
# @Software: PyCharm
# @Blog    : https://www.hecady.com
import datetime
from flask_jwt_extended import JWTManager, set_access_cookies
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
from flask import Flask, request, jsonify

app = Flask(__name__)

app.config['SECRET_KEY'] = 'super-secret'  # 设置秘钥
# 配置JWT

app.config['JWT_SECRET_KEY'] = 'super-secret'  # 设置JWT秘钥
app.config['JWT_TOKEN_LOCATION'] = ['headers', 'cookies']  # 设置token的位置
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = datetime.timedelta(days=7)  # 设置access_token过期时间
app.config['JWT_REFRESH_TOKEN_EXPIRES'] = datetime.timedelta(days=1)  # 设置refresh_token过期时间
app.config['JWT_COOKIE_SECURE'] = True  # 设置cookie只能通过https传输
app.config['JWT_ACCESS_COOKIE_PATH'] = '/'  # 设置access_token的cookie路径
app.config['JWT_REFRESH_COOKIE_PATH'] = '/refresh'  # 设置refresh_token的cookie路径

# 初始化jwt
jwt = JWTManager(app)


@app.route('/login', methods=['POST'])
def login():
    # 从请求的json数据中获取用户名和密码
    username = request.json.get('username', None)
    password = request.json.get('password', None)
    # 验证用户名和密码是否正确
    if username != 'admin' or password != '123456':
        return jsonify({'code': 401, 'msg': '用户名或密码错误'})
    else:
        # 生成access_token
        access_token = create_access_token(identity=username)
        # 将生成的token返回给前端
        response = jsonify({'code': 200, 'msg': '登录成功', 'access_token': access_token})
        return response


@app.route('/test', methods=['POST'])
@jwt_required(locations=['headers', 'cookies'])
def test():
    # 获取当前token的身份信息
    current_identity = get_jwt_identity()
    # 判断当前token是否存在
    if current_identity:
        # 返回当前token的身份信息
        return jsonify({'code': 200, 'msg': '请求成功', 'current_identity': current_identity})
    else:
        # 返回错误信息
        return jsonify({'code': 401, 'msg': '请先登录认证'})


if __name__ == '__main__':
    app.run(debug=True)

4、最后

至此flask_jwt_extended基本的使用方法就到这里了,都是我自己的一些,欢迎来讨论。

后面有时间也会持续更新。

下一篇文章讲一下使用携带cookie和设置cookie

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇