前端Python应用指南(六)构建RESTful API:使用Flask和Django实现用户认证与授权

《写给前端的python应用指南》系列:

在构建现代Web应用时,用户认证与授权是非常重要的部分。无论是通过用户名和密码登录,还是通过OAuth2、JWT等方式进行身份验证,确保只有授权的用户可以访问敏感数据是每个API设计的核心。本篇博文将详细介绍如何使用FlaskDjango构建RESTful API,并实现用户认证与授权功能,包括JWT(JSON Web Tokens)的使用。

一、概述

RESTful API通常用于前后端分离的应用,用户认证与授权机制用于保护API,使得只有经过认证的用户才能访问特定的资源。JWT(JSON Web Token)作为一种轻量级的认证方式,广泛应用于前后端分离的Web应用中。

在本文中,我们将分别使用FlaskDjango实现:

  • 用户注册
  • 用户登录(并生成JWT)
  • 保护需要授权的API(通过JWT)

二、Flask实现用户认证与授权

Flask是一个轻量级Web框架,非常适合用来快速构建RESTful API。我们将通过Flask和Flask-JWT-Extended扩展来实现JWT认证。

2.1 安装依赖

首先,我们需要安装Flask和Flask-JWT-Extended。

bash 复制代码
pip install flask flask-jwt-extended flask-sqlalchemy
2.2 创建Flask应用

我们将创建一个简单的Flask应用,包含用户注册、登录和JWT认证的功能。

  1. 初始化Flask应用:
python 复制代码
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'  # 使用SQLite数据库
app.config['JWT_SECRET_KEY'] = 'your_jwt_secret_key'  # JWT的密钥

db = SQLAlchemy(app)
jwt = JWTManager(app)
  1. 创建用户模型:

我们将创建一个用户模型,用户将具有usernamepassword字段。

python 复制代码
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(120), nullable=False)

    def __repr__(self):
        return f'<User {self.username}>'
  1. 用户注册:

用户注册时,我们将验证输入,并将密码进行哈希处理后存入数据库。

python 复制代码
from werkzeug.security import generate_password_hash

@app.route('/register', methods=['POST'])
def register():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    # 检查用户是否已存在
    if User.query.filter_by(username=username).first():
        return jsonify({"msg": "User already exists"}), 400

    # 哈希处理密码
    hashed_password = generate_password_hash(password, method='sha256')
    new_user = User(username=username, password=hashed_password)
    db.session.add(new_user)
    db.session.commit()

    return jsonify({"msg": "User created successfully"}), 201
  1. 用户登录并生成JWT:

用户登录时,我们验证用户名和密码是否匹配,若匹配则返回一个JWT。

python 复制代码
from werkzeug.security import check_password_hash

@app.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    user = User.query.filter_by(username=username).first()

    if user and check_password_hash(user.password, password):
        access_token = create_access_token(identity=username)
        return jsonify(access_token=access_token), 200
    else:
        return jsonify({"msg": "Invalid credentials"}), 401
  1. 受保护的API:

我们使用@jwt_required()装饰器来保护需要授权的API。用户必须在请求头中提供有效的JWT才能访问这些API。

python 复制代码
@app.route('/protected', methods=['GET'])
@jwt_required()
def protected():
    current_user = get_jwt_identity()  # 获取当前用户的身份信息
    return jsonify(logged_in_as=current_user), 200
  1. 运行Flask应用:
python 复制代码
if __name__ == '__main__':
    db.create_all()  # 创建数据库表
    app.run(debug=True)
2.3 测试Flask API

你可以使用Postman或者curl工具来测试这些API接口:

  • 注册用户POST /register

    • 请求体:{"username": "john", "password": "password123"}
    • 响应:{"msg": "User created successfully"}
  • 用户登录POST /login

    • 请求体:{"username": "john", "password": "password123"}
    • 响应:{"access_token": "jwt_token_here"}
  • 访问受保护的APIGET /protected

    • 请求头:Authorization: Bearer <jwt_token_here>
    • 响应:{"logged_in_as": "john"}

三、Django实现用户认证与授权

Django是一个功能强大的Web框架,适用于构建复杂的Web应用。在Django中实现JWT认证,我们通常会使用djangorestframeworkdjangorestframework-simplejwt这两个库来进行集成。

3.1 安装依赖

首先,我们需要安装Django、Django REST framework以及JWT相关库。

bash 复制代码
pip install django djangorestframework djangorestframework-simplejwt
3.2 创建Django项目和应用
bash 复制代码
django-admin startproject myproject
cd myproject
python manage.py startapp accounts
3.3 配置Django项目

myproject/settings.py中,添加rest_frameworkaccountsINSTALLED_APPS

python 复制代码
INSTALLED_APPS = [
    ...
    'rest_framework',
    'accounts',
]

然后,配置JWT设置:

python 复制代码
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
}
3.4 创建用户模型和序列化器

我们将在accounts/models.py中创建用户模型,并在accounts/serializers.py中创建序列化器。

  1. 创建用户模型:

accounts/models.py文件中,我们可以使用Django的默认用户模型或者自定义一个用户模型:

python 复制代码
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass
  1. 创建序列化器:

accounts/serializers.py文件中,我们为用户注册和登录创建序列化器:

python 复制代码
from rest_framework import serializers
from django.contrib.auth.models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['username', 'password']

    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        return user
3.5 创建视图和URL路由

accounts/views.py中,我们使用APIView来处理注册、登录以及JWT认证。

  1. 用户注册视图:
python 复制代码
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .serializers import UserSerializer

class RegisterView(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({"msg": "User created successfully"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
  1. 用户登录视图(获取JWT):
python 复制代码
from rest_framework_simplejwt.tokens import RefreshToken

class LoginView(APIView):
    def post(self, request):
        username = request.data.get("username")
        password = request.data.get("password")

        user = authenticate(username=username, password=password)
        if user:
            refresh = RefreshToken.for_user(user)
            access_token = str(refresh.access_token)
            return Response({"access_token": access_token}, status=status.HTTP_200_OK)
        return Response({"msg": "Invalid credentials"}, status=status.HTTP_401_UNAUTHORIZED)
  1. 受保护的视图:
python 复制代码
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView

class ProtectedView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({"msg": "You have access to this protected view."}, status=status.HTTP_200_OK)
3.6 配置URL路由

accounts/urls.py中,配置相应的路由:

python 复制代码
from django.urls import path
from .views import RegisterView, LoginView, ProtectedView

urlpatterns = [
    path('register/', RegisterView.as_view(), name='register'),
    path('login/', LoginView.as_view(), name='login'),
    path('protected

/', ProtectedView.as_view(), name='protected'),
]

myproject/urls.py中,包含accounts/urls.py

python 复制代码
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/accounts/', include('accounts.urls')),
]
3.7 运行Django项目
bash 复制代码
python manage.py runserver
3.8 测试Django API

使用Postman或curl测试以下API:

  • 注册用户POST /api/accounts/register/
  • 用户登录POST /api/accounts/login/
  • 访问受保护的APIGET /api/accounts/protected/(需要JWT令牌)

四、总结

通过本文的示例,我们分别展示了如何使用FlaskDjango实现用户认证与授权,保护RESTful API。两种框架都支持JWT认证,但在实现上有所不同:

  • Flask适合轻量级项目,灵活且简洁。
  • Django则更适合复杂的应用,具有更强的功能和更好的扩展性。

无论你选择Flask还是Django,它们都能提供高效、安全的认证方式,并能帮助你快速构建可扩展的RESTful API。希望本文的示例能帮助你在实际项目中更好地实现用户认证与授权功能!

相关推荐
大霸王龙3 分钟前
Python中PDF转Word的技术
python·pdf·word
老大白菜4 分钟前
python 选择排序(Selection Sort)
python·算法·排序算法
二川bro5 分钟前
图片叠加拖拽对比展示效果实现——Vue版
前端·vue.js
russle5 分钟前
android app构建时排除指定类
android·前端·chrome
愚愚是个大笨蛋10 分钟前
自定义VUE指定,实现鼠标悬停显示提示面板,离开元素或面板后面板消失
前端·javascript·vue.js
CSNMD11 分钟前
VueRouter之HelloWorld
前端·javascript·vue.js
Smileyqp沛沛12 分钟前
gz、zip等压缩文件postman成功下载但是前端项目中下载解压失败
前端·测试工具·postman
xcLeigh15 分钟前
HTML5实现好看的新年春节元旦网站源码
前端·html·html5
qq_4337169537 分钟前
微信小程序UI自动化测试实践 !
自动化测试·软件测试·python·selenium·测试工具·压力测试
存梨1 小时前
2024 年终总结
前端·react.js