在Web应用程序中,用户身份认证是一个非常重要且常见的功能。它确保只有授权的用户才能访问特定的资源和操作。在本篇博客中,将介绍如何使用Flask和JWT(JSON Web Token)进行用户身份认证。
什么是JWT?
JWT是一种用于身份验证和授权的安全传输的数据结构。它是一个加密签名的字符串,由三个部分组成:头、载荷和签名。头部包含加密算法和类型信息,载荷中包含身份验证的相关信息,签名用于验证数据的完整性和真实性。
JWT的一个巨大优势是它的无状态性,即服务器不需要在后端存储数据。这使得JWT成为构建可扩展和分布式应用程序的理想工具。
准备工作
在开始之前,确保已经在系统中安装了Python、Flask和PyJWT。可以使用以下命令安装它们:
$ pip install flask
$ pip install pyjwt
项目搭建
首先,创建一个名为app.py
的新文件,并在其中导入所需的模块:
from flask import Flask
from flask_jwt import JWT
from flask import jsonify
from werkzeug.security import safe_str_cmp
然后,初始化一个Flask应用程序:
app = Flask(__name__)
app.config['SECRET_KEY'] = 'super-secret' # 用于JWT的签名密钥
接下来,定义一个用户类来模拟数据库中的用户记录:
class User:
def __init__(self, id, username, password):
self.id = id
self.username = username
self.password = password
users = [
User(1, 'user1', 'password1'),
User(2, 'user2', 'password2')
]
然后,创建一个身份验证函数,用于验证用户的用户名和密码是否正确:
def authenticate(username, password):
for user in users:
if user.username == username and user.password == password:
return user
def identity(payload):
user_id = payload['identity']
for user in users:
if user.id == user_id:
return user
接下来,将authenticate
和identity
函数传递给JWT对象来进行身份验证和授权:
jwt = JWT(app, authenticate, identity)
现在,可以编写几个路由来测试身份认证的功能。在路由中,使用@jwt_required()
装饰器来保护需要身份认证的资源:
@app.route('/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
user = authenticate(username, password)
if user:
token = jwt.jwt_encode_callback(user)
return jsonify({'token': token})
else:
return jsonify({'error': 'Invalid credentials'}), 401
@app.route('/protected', methods=['GET'])
@jwt_required()
def protected():
return jsonify({'message': 'You are accessing protected resource'})
测试身份认证
现在,即可以使用任意的HTTP客户端来测试身份认证功能。首先,确保Flask应用程序已经启动。然后,发送一个POST请求到/login
:
$ curl --header "Content-Type: application/json" \
--request POST \
--data '{"username":"user1","password":"password1"}' \
http://localhost:5000/login
将会得到一个包含JWT的响应:
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSIsImlhdCI6MTYyMzczODQyOCwiZXhwIjoxNjIzNzQyMDI4fQ.FifPOuMyIiLfrO_im_Aa6OTWcBotKJ7KZIoljHa26Ns"}
使用这个JWT令牌,在请求中包含Authorization
头来访问受保护的资源:
$ curl --header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSIsImlhdCI6MTYyMzczODQyOCwiZXhwIjoxNjIzNzQyMDI4fQ.FifPOuMyIiLfrO_im_Aa6OTWcBotKJ7KZIoljHa26Ns" \
http://localhost:5000/protected
将会得到一个包含"message"的响应:
{"message":"You are accessing protected resource"}
如果不使用JWT令牌,或者提供的令牌无效或已过期,则会收到401错误。
结论
本篇博客中,介绍了如何使用Flask和JWT进行用户身份认证。通过创建一个Flask应用程序,定义用户类和相关的身份认证函数,以及使用JWT对象来保护需要身份认证的资源,可以实现简单而强大的用户身份认证功能。这对于构建安全的Web应用程序来说非常重要,因为只有经过身份验证和授权的用户才能访问受保护的资源。
本文来自极简博客,作者:绮梦之旅,转载请注明原文链接:使用Flask和JWT进行用户身份认证