MST

星途 面试题库

面试题:Python RESTful API的安全认证

在使用Python实现RESTful API时,如何实现基于令牌(Token)的认证机制?描述整个实现流程,并且说明如何在Flask或Django框架中集成这种认证机制,以确保API的安全性。
35.7万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

基于令牌(Token)认证机制实现流程

  1. 生成令牌
    • 用户提供用户名和密码进行登录。
    • 应用程序验证用户名和密码是否正确。
    • 如果验证成功,生成一个唯一的令牌。通常可以使用诸如PyJWT(Python JSON Web Token)库来生成令牌。例如,使用PyJWT库:
import jwt
from datetime import datetime, timedelta

def generate_token(user_id):
    payload = {
        'user_id': user_id,
        'exp': datetime.utcnow() + timedelta(minutes=30)  # 设置令牌过期时间
    }
    token = jwt.encode(payload, 'your_secret_key', algorithm='HS256')
    return token
  1. 存储令牌
    • 生成的令牌可以存储在客户端,通常是在浏览器的本地存储或者Cookie中(需注意Cookie的安全性,防止跨站脚本攻击等问题)。
    • 在服务器端,对于短期令牌可以不存储,但对于长期令牌(如刷新令牌),可以存储在数据库中,关联到对应的用户。
  2. 验证令牌
    • 客户端在每次请求API时,将令牌包含在请求头(如Authorization: Bearer <token>)或者请求参数中发送到服务器。
    • 服务器接收到请求后,从请求中提取令牌。
    • 使用相应的库(如PyJWT)验证令牌的有效性,包括令牌是否过期、签名是否正确等。例如:
def verify_token(token):
    try:
        data = jwt.decode(token, 'your_secret_key', algorithms=['HS256'])
        return data
    except jwt.ExpiredSignatureError:
        return None
    except jwt.InvalidTokenError:
        return None

在Flask框架中集成令牌认证机制

  1. 安装必要库
    • 安装FlaskPyJWT库。
    pip install flask PyJWT
    
  2. 创建Flask应用并集成认证
from flask import Flask, request, jsonify
import jwt

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'


def verify_token(token):
    try:
        data = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
        return data
    except jwt.ExpiredSignatureError:
        return None
    except jwt.InvalidTokenError:
        return None


@app.before_request
def before_request():
    token = None
    if 'Authorization' in request.headers:
        token = request.headers['Authorization'].split(' ')[1]
    if not token:
        return jsonify({'message': 'Token is missing!'}), 401
    data = verify_token(token)
    if not data:
        return jsonify({'message': 'Token is invalid!'}), 401


@app.route('/protected')
def protected():
    return jsonify({'message': 'This is a protected route'})


if __name__ == '__main__':
    app.run(debug=True)

在Django框架中集成令牌认证机制

  1. 安装必要库
    • 安装djangorestframeworkPyJWT库。
    pip install djangorestframework PyJWT
    
  2. 配置Django项目
    • settings.py中添加rest_frameworkINSTALLED_APPS
    INSTALLED_APPS = [
       ...
       'rest_framework',
    ]
    
    • 配置认证类。在settings.py中添加:
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': (
           'rest_framework_simplejwt.authentication.JWTAuthentication',
        )
    }
    
  3. 使用Django REST framework的视图和序列化器
    • 创建视图和序列化器处理用户认证和API请求,例如:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth.models import User
from.serializers import UserSerializer


class UserLoginView(APIView):
    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = User.objects.filter(username=username, password=password).first()
        if user:
            refresh = RefreshToken.for_user(user)
            return Response({
               'refresh': str(refresh),
                'access': str(refresh.access_token),
            }, status=status.HTTP_200_OK)
        return Response({'message': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED)


class ProtectedView(APIView):
    def get(self, request):
        return Response({'message': 'This is a protected route'})
  • 配置URLs映射到这些视图。在urls.py中:
from django.urls import path
from.views import UserLoginView, ProtectedView

urlpatterns = [
    path('login/', UserLoginView.as_view(), name='login'),
    path('protected/', ProtectedView.as_view(), name='protected'),
]