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

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

  • (一)快速构建 Web 服务器 - Flask vs Node.js 对比
  • (二)深入Flask:理解Flask的应用结构与模块化设计
  • (三)Django vs Flask:哪种框架适合构建你的下一个Web应用?
  • (四)Django实战:创建一个简单的博客系统
  • (五)用FastAPI快速构建高性能API

在构建现代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。

pip install flask flask-jwt-extended flask-sqlalchemy
2.2 创建Flask应用

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

  1. 初始化Flask应用:
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字段。

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. 用户注册:

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

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。

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。

@app.route('/protected', methods=['GET'])
@jwt_required()
def protected():
    current_user = get_jwt_identity()  # 获取当前用户的身份信息
    return jsonify(logged_in_as=current_user), 200
  1. 运行Flask应用:
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相关库。

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

myproject/settings.py中,添加rest_frameworkaccountsINSTALLED_APPS

INSTALLED_APPS = [
    ...
    'rest_framework',
    'accounts',
]

然后,配置JWT设置:

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

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

  1. 创建用户模型:

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

from django.contrib.auth.models import AbstractUser

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

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

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. 用户注册视图:
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):
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. 受保护的视图:
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中,配置相应的路由:

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/946337.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql乱码、mysql数据中文问号

网上排出此错误方法的很多&#xff0c;但是 都不简洁&#xff0c;找不到根本原因 主要排查两点&#xff1a; 1.代码中jdbc链接的编码规则 urljdbc:mysql://localhost:3306/title?useUnicodetrue&amp;characterEncodingutf8 将characterEncoding设置为utf8 2.设置mysq…

Presto-简单了解-230403

presto是什么了解一下&#xff1a; 秒级查询引擎&#xff08;不做存储&#xff09;&#xff0c;GB-PB级不依赖于yarn&#xff0c;有自己的资源管理和执行计划支持多种数据源&#xff1a;hive、redis、kafka presto架构 presto优缺点 presto优点 内存到内存的传输&#xff0…

openGauss连接是报org.opengauss.util.PSQLException: 尝试连线已失败

安装好高斯数据库后然后用java连接时报如下错误: 解决方法: 在openGauss数据库的安装路径下/opt/opengauss/data/single_node&#xff08;这个路径根据自己实际情况变化&#xff09;有个pg_hba.conf文件&#xff0c;修改里面host内容如下&#xff0c;我这里设置的是所有ip都能…

mybatis-plus自动填充时间的配置类实现

mybatis-plus自动填充时间的配置类实现 在实际操作过程中&#xff0c;我们并不希望创建时间、修改时间这些来手动进行&#xff0c;而是希望通过自动化来完成&#xff0c;而mybatis-plus则也提供了自动填充功能来实现这一操作&#xff0c;接下来&#xff0c;就来了解一下mybatis…

【Java项目】基于SpringBoot的【人职匹配推荐系统】

【Java项目】基于SpringBoot的【人职匹配推荐系统】 技术简介&#xff1a;本系统使用采用B/S架构、Spring Boot框架、MYSQL数据库进行开发设计。 系统简介&#xff1a;人职匹配推荐系统分为管理员和用户、企业三个权限子模块。 管理员所能使用的功能主要有&#xff1a;首页、个…

Flutter 调试环境下浏览器网络请求跨域问题解决方案

本篇文章主要讲解&#xff0c;Flutter调试环境情况下&#xff0c;浏览器调试报错跨域问题的解决方法&#xff0c;通过本篇文章你可以快速掌握Flutter调试环境情况下的跨域问题。 日期&#xff1a;2024年12月28日 作者&#xff1a;任聪聪 报错现象&#xff1a; 报文信息&#xf…

【每日学点鸿蒙知识】导入cardEmulation、自定义装饰器、CallState状态码顺序、kv配置、签名文件配置

1、HarmonyOS 无法导入cardEmulation&#xff1f; 在工程entry mudule里的index.ets文件里导入cardEmulation失败 可以按照下面方式添加SystemCapability&#xff1b;在src/main/syscap.json(此文件需要手动创建&#xff09;中添加如下内容 {"devices": {"gen…

ArcGIS JSAPI 高级教程 - 通过RenderNode实现视频融合效果(不借助三方工具)

ArcGIS JSAPI 高级教程 - 通过RenderNode实现视频融合效果&#xff08;不借助三方工具&#xff09; 核心代码完整代码在线示例 地球中展示视频可以通过替换纹理的方式实现&#xff0c;但是随着摄像头和无人机的流行&#xff0c;需要视频和场景深度融合&#xff0c;简单的实现方…

【大模型实战篇】LLaMA Factory微调ChatGLM-4-9B模型

1. 背景介绍 虽然现在大模型微调的文章很多&#xff0c;但纸上得来终觉浅&#xff0c;大模型微调的体感还是需要自己亲自上手实操过&#xff0c;才能有一些自己的感悟和直觉。这次我们选择使用llama_factory来微调chatglm-4-9B大模型。 之前微调我们是用两块3090GPU显卡&…

微信流量主挑战:三天25用户!功能未完善?(新纪元4)

&#x1f389;【小程序上线第三天&#xff01;突破25用户大关&#xff01;】&#x1f389; 嘿&#xff0c;大家好&#xff01;今天是我们小程序上线的第三天&#xff0c;我们的用户量已经突破了25个&#xff01;昨天还是16个&#xff0c;今天一觉醒来竟然有25个&#xff01;这涨…

【工具变量】国际消费中心城市DID数据(2007年-2023年)

数据简介 国际消费中心城市的定位是一个国家乃至全球消费市场消费资源的集中地和关键枢纽&#xff0c;该城市特质不单顺应我国对外交流与开放的不断扩大的趋势&#xff0c;其培育和建设国际消费中心城市的一大意义在于&#xff0c;以地区地域资源中心定位&#xff0c;来推动周围…

如何修复 WordPress 中的“Error establishing a database connection”问题

如何修复 WordPress 中的“Error establishing a database connection”问题 在使用 WordPress 建站时&#xff0c;如果你看到“Error establishing a database connection”的提示&#xff0c;不要慌张。这通常意味着网站无法连接到数据库&#xff0c;因此无法显示内容。下面…

streamlit、shiny、gradio、fastapi四个web APP平台体验

streamlit、shiny、gradio、fastapi四个web APP平台体验 经常被问的问题就是&#xff1a;web APP平台哪个好&#xff1f;该用哪个&#xff1f;刚开始只有用streamlit和shiny&#xff0c;最近体验了一下gradio和fastapi&#xff0c;今天根据自己的体会尝试着回答一下。 使用R语…

http报头解析

http报文 http报文主要有两类是常见的&#xff0c;第一类是请求报文&#xff0c;第二类是响应报文&#xff0c;每个报头除了第一行&#xff0c;都是采用键值对进行传输数据&#xff0c;请求报文的第一行主要包括http方法&#xff08;GET&#xff0c;PUT&#xff0c; POST&#…

Qwen-Agent

文章目录 一、关于 Qwen-Agent更新准备&#xff1a;模型服务免责声明 二、安装三、快速开发步骤 1&#xff1a;添加自定义工具步骤 2&#xff1a;配置 LLM步骤 3&#xff1a;创建智能体步骤 4&#xff1a;运行智能体 四、FAQ1、支持函数调用&#xff08;也称为工具调用&#xf…

flux文生图模型实践

flux文生图模型实践 flyfish https://github.com/black-forest-labs/flux Black Forest Labs发布FLUX.1 Tools&#xff0c;这是一套模型全家桶&#xff0c;旨在为FLUX.1基础文本转图像模型添加控制和可操纵性&#xff0c;从而实现对真实图像和生成图像的修改和重新创建。FLU…

【ETCD】【实操篇(十九)】ETCD基准测试实战

目录 1. 设定性能基准要求2. 使用基准测试工具基准测试命令 3. 测试不同的负载和场景4. 监控集群性能5. 评估硬件和网络的影响6. 对比性能基准7. 负载均衡和容错能力测试8. 优化与调优9. 测试在高负载下的表现总结 1. 设定性能基准要求 首先&#xff0c;明确集群性能的目标&am…

Docker Compose 构建 EMQX 集群 实现mqqt 和websocket

EMQX 集群化管理mqqt真香 目录 #目录 /usr/emqx 容器构建 vim docker-compose.yml version: 3services:emqx1:image: emqx:5.8.3container_name: emqx1environment:- "EMQX_NODE_NAMEemqxnode1.emqx.io"- "EMQX_CLUSTER__DISCOVERY_STRATEGYstatic"- …

【Cesium】三、实现开场动画效果

文章目录 实现效果实现方法实现代码组件化 实现效果 实现方法 Cesium官方提供了Camera的flyTo方法实现了飞向目的地的动画效果。 官方API&#xff1a;传送门 这里只需要用到目的地&#xff08;destination&#xff09;和持续时间&#xff08;duration&#xff09;这两个参数…

Qt从入门到入土(七)-实现炫酷的登录注册界面(下)

前言 Qt从入门到入土&#xff08;六&#xff09;-实现炫酷的登录注册界面&#xff08;上&#xff09;主要讲了如何使用QSS样式表进行登录注册的界面设计&#xff0c;本篇文章将介绍如何对登录注册界面进行整体控件的布局&#xff0c;界面的切换以及实现登录、记住密码等功能。…