1. 中间件
- 安全中间件:
- Django自带中间件:启用
django.middleware.security.SecurityMiddleware
,它会添加一些安全相关的HTTP头,如X-Frame-Options
、X-Content-Type-Options
等,有助于防止点击劫持和MIME类型嗅探攻击。
- CSRF(Cross - Site Request Forgery)中间件:Django默认启用
django.middleware.csrf.CsrfViewMiddleware
,用于防止跨站请求伪造攻击。对于RESTful API,可根据实际情况(如使用Token认证时)适当调整其配置,在非浏览器场景下可以考虑使用基于Token的认证机制来替代传统的CSRF防护。
- SQL注入防护:
- ORM(Object - Relational Mapping)使用:在Django项目中,推荐使用Django的ORM进行数据库操作,它会自动对输入进行转义,防止SQL注入。例如,使用
filter()
、exclude()
等方法构建查询语句,而不是手动拼接SQL字符串。
- 参数化查询:如果确实需要执行原生SQL,使用
raw()
方法并传递参数,确保参数被正确处理。例如:MyModel.objects.raw('SELECT * FROM my_table WHERE column = %s', [param_value])
。
- XSS防护:
- 自动转义:Django模板系统默认对变量进行自动转义,以防止XSS攻击。确保在输出数据到模板时不关闭自动转义功能。如果是API返回数据,确保在返回前对可能包含HTML标签的数据进行适当的清理或转义。例如,使用
bleach
库对输入输出的数据进行清洗,只允许特定的HTML标签和属性。
2. 安全头配置
- Content - Security - Policy(CSP):通过
django - cors - headers
库或在settings.py
中手动配置,设置Content - Security - Policy
头,限制页面可以加载的资源来源,防止XSS攻击。例如:
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_BROWSER_XSS_FILTER = True
CSP_DEFAULT_SRC = ("'self'",)
CSP_SCRIPT_SRC = ("'self'",)
CSP_STYLE_SRC = ("'self'",)
- X - Frame - Options:设置
X - Frame - Options
头为DENY
或SAMEORIGIN
,防止点击劫持。在settings.py
中配置:
X_FRAME_OPTIONS = 'DENY'
- X - Content - Type - Options:设置
X - Content - Type - Options
头为nosniff
,防止浏览器进行MIME类型嗅探,在settings.py
中配置:
SECURE_CONTENT_TYPE_NOSNIFF = True
3. 跨域处理策略
- 使用
django - cors - headers
库:
- 安装:
pip install django - cors - headers
。
- 配置:在
settings.py
中添加'corsheaders'
到INSTALLED_APPS
,并配置允许的跨域源。例如:
INSTALLED_APPS = [
...
'corsheaders',
...
]
CORS_ALLOWED_ORIGINS = [
"https://allowed - frontend - 1.com",
"https://allowed - frontend - 2.com",
]
- **细粒度控制**:可以根据不同的视图或URL模式进行更细粒度的跨域控制,通过`CORS_ALLOW_METHODS`、`CORS_ALLOW_HEADERS`等设置允许的HTTP方法和请求头。
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
]
CORS_ALLOW_HEADERS = [
'accept',
'accept - encoding',
'authorization',
'content - type',
'dnt',
'origin',
'user - agent',
'x - csrf - token',
'x - requested - with',
]
4. 与OAuth 2.0认证服务集成
- 选择OAuth 2.0库:例如
djangorestframework - simplejwt
结合django - oauth - toolkit
。
djangorestframework - simplejwt
:用于生成和验证JSON Web Tokens(JWT)。安装:pip install djangorestframework - simplejwt
。在settings.py
中配置:
from datetime import timedelta
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes = 15),
'REFRESH_TOKEN_LIFETIME': timedelta(days = 1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUTH_HEADER_TYPES': ('Bearer',),
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM':'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes = 5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days = 1),
}
- **`django - oauth - toolkit`**:实现OAuth 2.0协议。安装:`pip install django - oauth - toolkit`。在`settings.py`中配置:
INSTALLED_APPS = (
...
'oauth2_provider',
...
)
OAUTH2_PROVIDER = {
# this is the list of available scopes
'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'}
}
- 配置视图和URL:
- 使用
oauth2_provider.views
中的视图类来处理OAuth 2.0的授权、令牌获取等流程,并在urls.py
中配置相应的URL。例如:
from django.urls import path
from oauth2_provider.views import AuthorizationView, TokenView
urlpatterns = [
path('o/authorize/', AuthorizationView.as_view(), name = 'authorize'),
path('o/token/', TokenView.as_view(), name = 'token'),
...
]
- 保护API视图:在需要保护的API视图上使用
oauth2_provider.contrib.rest_framework.OAuth2Authentication
或rest_framework_simplejwt.authentication.JWTAuthentication
进行认证,确保只有经过授权的用户才能访问API。例如:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from oauth2_provider.contrib.rest_framework import OAuth2Authentication
from rest_framework_simplejwt.authentication import JWTAuthentication
class MyProtectedAPIView(APIView):
authentication_classes = [OAuth2Authentication, JWTAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request):
return Response({'message': 'This is a protected API'})