前端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。希望本文的示例能帮助你在实际项目中更好地实现用户认证与授权功能!

相关推荐
Moment1 小时前
从方案到原理,带你从零到一实现一个 前端白屏 检测的 SDK ☺️☺️☺️
前端·javascript·面试
鱼樱前端1 小时前
Vue3 + TypeScript 整合 MeScroll.js 组件
前端·vue.js
zimoyin2 小时前
解决 Java/Kotlin 资源加载问题
java·python·kotlin
拉不动的猪2 小时前
刷刷题29
前端·vue.js·面试
wjcroom2 小时前
数字投屏叫号器-发射端python窗口定制
开发语言·python
静候光阴2 小时前
python使用venv命令创建虚拟环境(ubuntu22)
linux·开发语言·python
野生的程序媛2 小时前
重生之我在学Vue--第5天 Vue 3 路由管理(Vue Router)
前端·javascript·vue.js
codingandsleeping2 小时前
前端工程化之模块化
前端·javascript
CodeCraft Studio2 小时前
报表控件stimulsoft操作:使用 Angular 应用程序的报告查看器组件
前端·javascript·angular.js
Y1nhl2 小时前
力扣hot100_二叉树(4)_python版本
开发语言·pytorch·python·算法·leetcode·机器学习