📌  相关文章
📜  在 Flask 中使用 JWT 进行用户身份验证(1)

📅  最后修改于: 2023-12-03 15:37:20.171000             🧑  作者: Mango

在 Flask 中使用 JWT 进行用户身份验证

在现代应用程序中,保护用户资源和数据是非常重要的。使用 JSON Web Token (JWT) 技术实现用户身份验证是当今最流行的方式之一。在 Flask 中使用 JWT 允许应用程序验证用户身份并授予他们访问他们需要的资源的权限。

本文将介绍如何在 Flask 中使用 JWT 实现用户身份验证。

什么是 JWT

JSON Web Token (JWT) 是一种轻量级的身份验证协议。它由三部分组成:Header、Payload 和 Signature。

Header 包含 token 的类型和算法。

Payload 是存储在 token 中的 JSON 数据。它包含自定义的声明和标准的声明。标准声明包括:iss(发行人)、exp(到期时间戳)、sub(主题)和 aud(受众)。

Signature 是由头部、负载和密钥生成的哈希值。它用于验证 token 的完整性,并防止篡改。

安装依赖

在 Flask 中使用 JWT 需要安装 Flask 和 PyJWT 库。可以使用以下命令安装它们:

pip install Flask PyJWT
实现 JWT 身份验证

尽管使用 JWT 进行身份验证的实现方式有很多方法,但以下是 Flask JWT 的一个典型的实现方式。

创建 JWT

创建 JWT 要求以下信息:

  1. 用户 id
  2. 过期时间(此 token 的有效期)
  3. 应用程序密钥(用于签名 token)

我们将创建一个名为 create_jwt 的函数,它将在用户成功登录后被调用。用户通过调用此函数生成一个 JWT,返回给客户端存储并在进行任何资源请求时发送回服务器。

def create_jwt(user_id):
    payload = {
        "user_id": user_id,
        "exp": datetime.utcnow() + timedelta(days=1)
    }
    token = jwt.encode(payload, app.config['SECRET_KEY'], algorithm='HS256')
    return token

在此示例中,我们创建一个名为 payload 的字典,其 "user_id" 键包含用户 id,"exp" 键包含当前 UTC 时间 + 1 天的时间戳,将其作为一个负载使用 PyJWT 库中的 jwt.encode() 编码生成 token。在 Flask 应用程序中,通常将应用程序密钥存储在 SECRET_KEY 配置选项中。

验证 JWT

在服务器收到包含 token 的请求后,需要对 token 进行验证以确保它有效。我们将实现一个名为 validate_jwt 的中间件函数,用于验证 token 的完整性、过期时间和签名。

def validate_jwt(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        token = request.headers['Authorization'].split(' ')[1]
        try:
            jwt.decode(
                token, 
                app.config['SECRET_KEY'], 
                algorithms=['HS256']
            )
        except jwt.ExpiredSignatureError:
            return jsonify({"message": "Token has expired"}), 401
        except jwt.InvalidTokenError:
            return jsonify({"message": "Invalid token"}), 401
        return func(*args, **kwargs)
    return wrapper

在这个函数中,我们使用 @wraps 装饰器将原始函数的元数据添加到 wrapper 函数中,并解析传递请求 headers 值中的 token。如果 token 验证成功,那么将直接返回包含函数元素的结果。如果 token 值不被 PyJWT 签名接受或者已过期,那么会返回 401 响应状态码。

应用 JWT 验证

现在,我们可以将 validate_jwt 中间件添加到需要进行身份验证的资源请求上。可以在 Flask 路由上使用 @validate_jwt 装饰器来检查这个请求是否有有效的 token。

@app.route('/profile', methods=['GET'])
@validate_jwt
def profile():
    user_id = request.headers['Authorization']
    # code to retrieve user profile data

在这个示例中,在 /profile 路由中添加了 @validate_jwt 装饰器。如果请求中没有有效的 token,那么在中间件函数中返回 401 响应状态码。

结论

通过 Python 和 Flask 提供的 PyJWT 库,我们可以轻松地实现使用 JWT 进行身份验证的应用程序。在完成本文示例后,您应该对如何实现 Flask 中的 JWT 身份验证有了更深入的了解。如果您对 JWT 协议有更多的兴趣,建议查看官方文档以获取更多信息。