Skip to content

Flask 插件 - 鉴权


简介

鉴权是指验证用户身份的过程。身份验证的目的是确保只有经过授权的个人才能访问敏感信息或资源。


JWT(JSON Web 令牌)

jwt 是一种标准,用于在各方之间作为 JSON 对象安全地传输信息。通常用于传输用户身份和授权信息等信息。


Flask-JWT

Flask-JWT 是一个用于在 Flask 应用程序中实现 JWT 身份验证的扩展。它使用 PyJWT 库来实现 JWT 功能,并提供了一个简单的接口,使得在 Flask 应用程序中使用 JWT 变得更加容易。


操作步骤

安装相关依赖

pip install flask==2.3.3
pip install Flask-JWT==0.3.2

代码示例

根据 flask-jwt 的官网示例完成代码演示。

首先,先编写一个用户类,这里为了示范,简单的编写一下用户的信息用来认证,实际的用户信息一般是从数据库里面获取。

然后编写鉴权和返回用户标识的函数,绑定到对应的 flask 应用上,这样就成功把 flask-jwt 集成到 flask 上了。

from datetime import timedelta
from flask import Flask
from flask_jwt import JWT, jwt_required, current_identity

# 声明用户类
class User(object):
    def __init__(self, id, username, password):
        self.id = id
        self.username = username
        self.password = password

    def __str__(self):
        return "User(id='%s')" % self.id

# 使用硬编码保存用户数据,实际的数据来源一般是数据库
users = [
    User(1, 'user1', 'abcxyz'),
    User(2, 'user2', 'abcxyz'),
]

username_table = {u.username: u for u in users}
userid_table = {u.id: u for u in users}

# 编写鉴权的函数
def authenticate(username, password):
    user = username_table.get(username, None)
    if user and user.password.encode('utf-8') == password.encode('utf-8'):
        return user

# 编写返回用户标识的函数
def identity(payload):
    user_id = payload['identity']
    return userid_table.get(user_id, None)

app = Flask(__name__)
app.debug = True
# 配置 jwt 密钥
app.config['SECRET_KEY'] = 'super-secret'
# 配置 jwt 的过期时间为 6 分钟
app.config['JWT_EXPIRATION_DELTA'] = timedelta(seconds=360)
# 与 flask 应用做绑定
jwt = JWT(app, authenticate, identity)

# 需要鉴权的接口加上装饰器 jwt_required
@app.route('/protected')
@jwt_required()
def protected():
    return '%s' % current_identity

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

启动服务

这个时候就已经写好了一个带 jwt 认证的服务。

先启动这个服务,可以看到控制台会报错,导致我们无法正常的启动服务。 这个报错的原因是因为 flask-jwt 是基于 pyjwt 进行开发的,但是它所使用的 pyjwt 的版本需要再手动更新一下 ImportError: cannot import name 'Mapping' from 'collections' (D:\work\python310\lib\collections\__init__.py)


指定 pyjwt 的版本为 1.7.1 进行更新,注意这里不能使用最新版的 pyjwt,否则在实际使用会出现编码的问题。

升级完成之后,可以看到,已经可以正常的启动服务了。

pip install pyjwt==1.7.1


请求服务

接下来就可以通过 postman 来对它进行操作。

登录操作:

  • 请求的 url:http://127.0.0.1:5000/auth
  • 请求方法:post
  • 请求参数:
    {
    "username": "user1",
    "password": "abcxyz"
    }
    

  • 点击请求之后,这里我们就可以拿到登录的 token 了
    {
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NzY4Nzk4MzQsImlhdCI6MTY3Njg3OTQ3NCwibmJmIjoxNjc2ODc5NDc0LCJpZGVudGl0eSI6MX0.PEBWN4k7qM0bFfwVq66H4Jq1ZhUXRRqR0m6-6L4DP7A"
    }
    

然后可以通过这个 token 去访问需要鉴权的接口,要注意传这个 token 的时候需要带上JWT这个公共前缀。

点击请求之后,可以看到这个需要鉴权的接口,已经可以正常的返回它的信息了。


  • 请求的 url:http://127.0.0.1:5000/protected
  • 请求方法:get
  • headers:
    {
    "Authorization": "JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NzY4ODAwODEsImlhdCI6MTY3Njg3OTcyMSwibmJmIjoxNjc2ODc5NzIxLCJpZGVudGl0eSI6MX0.L2yjLvIZx6E_chmvZ7V94gfTan1QNLr0yiBHSbnN25U"
    }
    

flask-jwt 常用配置

接下来看一些常用的 flask-jwt 的配置。

可以通过这样对配置进行修改,大家根据需要修改对应的配置即可。

app.config['JWT_EXPIRATION_DELTA'] = timedelta(seconds=360)

  • JWT_EXPIRATION_DELTA:JWT 的过期时间。它可以是一个时间间隔对象,也可以是一个整数,表示过期时间的秒数。默认值为 datetime.timedelta(seconds=300),即 5 分钟。
  • JWT_AUTH_URL_RULE:用于生成 JWT 的认证 URL。默认值为 /auth
  • JWT_AUTH_USERNAME_KEY:用于从认证请求中提取用户名的参数名称。默认值为 username。
  • JWT_AUTH_PASSWORD_KEY:用于从认证请求中提取密码的参数名称。默认值为 password。
  • JWT_AUTH_HEADER_PREFIX:Authorization 标头值前缀。默认为 JWT,以便与 OAuth2 承载令牌不冲突,不区分大小写。

总结

  • flask-jwt 安装
  • 使用 flask-jwt 完成接口鉴权