0 32 2025-03-28 18:07:47
收藏
# utils/tokens.py
from rest_framework_simplejwt.tokens import AccessToken
from hashlib import sha256
class FingerprintedAccessToken(AccessToken):
def __init__(self, user, request=None, *args, **kwargs):
super().__init__(*args, **kwargs)
# 生成指纹(示例:User-Agent + IP 的哈希)
if request:
fingerprint_source = f"{request.META.get('HTTP_USER_AGENT')}:{request.META.get('REMOTE_ADDR')}"
self.payload['fingerprint'] = sha256(fingerprint_source.encode()).hexdigest()
# 绑定用户ID
self.payload['user_id'] = user.id
# authentication.py
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.exceptions import AuthenticationFailed
class FingerprintJWTAuthentication(JWTAuthentication):
def get_user(self, validated_token):
user = super().get_user(validated_token)
# 获取当前请求指纹
request = self.request
current_fp_source = f"{request.META.get('HTTP_USER_AGENT')}:{request.META.get('REMOTE_ADDR')}"
current_fp = sha256(current_fp_source.encode()).hexdigest()
# 验证指纹
if validated_token.get('fingerprint') != current_fp:
raise AuthenticationFailed("Token 指纹不匹配,可能已被盗用")
return user
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from utils.tokens import FingerprintedAccessToken
class LoginView(APIView):
def post(self, request):
user = authenticate(username=request.data['username'], password=request.data['password'])
if not user:
return Response({"error": "认证失败"}, status=401)
# 生成带指纹的 Token
access = FingerprintedAccessToken(user, request=request)
refresh = FingerprintedRefreshToken(user, request=request) # 同样实现RefreshToken
return Response({
"access": str(access),
"refresh": str(refresh)
})
# settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'yourapp.authentication.FingerprintJWTAuthentication', # 替换默认JWT认证
]
}
// 前端生成设备指纹(示例)
function generateFingerprint() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.fillText('Fingerprint', 10, 10);
return canvas.toDataURL().hashCode(); // 简单哈希生成
}
// 登录时附加指纹
fetch('/api/login', {
method: 'POST',
headers: {
'X-Device-Fingerprint': generateFingerprint()
}
})
fingerprint_source = f"{request.META.get('HTTP_USER_AGENT')}:{request.headers.get('X-Device-Fingerprint')}"
# models.py
from django.db import models
class AllowedDevice(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
fingerprint = models.CharField(max_length=64) # 存储指纹哈希
last_used = models.DateTimeField(auto_now=True)
# authentication.py 中增加检查
if not AllowedDevice.objects.filter(user=user, fingerprint=current_fp).exists():
raise AuthenticationFailed("未授权的设备")
# 允许IP在一定范围内变化(如动态IP)
def is_fingerprint_valid(saved_fp, current_fp):
# 简单实现:比对除IP外的部分
saved_parts = saved_fp.split(':')
current_parts = current_fp.split(':')
return saved_parts[0] == current_parts[0] # 只比较User-Agent部分
# tests.py
from django.test import TestCase
from utils.tokens import FingerprintedAccessToken
class TestFingerprint(TestCase):
def test_token_reuse(self):
user = User.objects.create(username="test")
request1 = self.factory.get('/', HTTP_USER_AGENT='Mozilla', REMOTE_ADDR='192.168.1.1')
token = FingerprintedAccessToken(user, request=request1)
# 模拟不同设备使用同一Token
request2 = self.factory.get('/', HTTP_USER_AGENT='Chrome', REMOTE_ADDR='192.168.1.2')
request2.META['HTTP_AUTHORIZATION'] = f'Bearer {str(token)}'
response = self.client.get('/protected', **{'HTTP_AUTHORIZATION': f'Bearer {str(token)}'})
self.assertEqual(response.status_code, 401) # 应拒绝访问
放宽 IP 检查规则
改用设备唯一标识(如 Android ID 或 iOS IDFV)
# 部分接口放宽检查(如公开API)
class SomeView(APIView):
authentication_classes = [] # 禁用指纹验证
本文地址:https://xzo.com.cn/develop/python/1273.html
如果您认可我们的分享,有意与我们合作开展帝国cms网站建设与开发业务或插件定制,请联系右侧在线客服。我们能给您的,就是高质量的模板与售后。
标注了信息来源为下载鸥的文章皆为原创,如果是转载的优质文章,我们也都标注了出处。如果您喜欢我们的文章,请按照下载鸥所标注的文章出处进行标注,谢谢您的配合。
Python免费、开源、简单,且含有海量的库。其功能也十分强大,不仅可以做网站、做爬虫、还可以做大数据、做人脸识别,等等等等。如果是新手入门,我们建议是首选Python。
国内知名度比较高的Python中文分词有哈工大LTP、中科院计算所NLPIR、清华大...
结巴分词支持3种模式:全模式、精确模式和搜索引擎模式,不同的模式效果会有差...
但凡对电脑知识了解多一点的朋友可能就听说过进程,而如果对蜘蛛爬虫有了解,那...
python爬虫爬取百度图片是很多人python爬虫入门后一个重要的练手项目。一方...
爬虫软件很多,支持爬虫功能的语言也很多,而用python做爬虫,辅以包罗万象的pyth...
通过本插件,可以实现帝国cms网站对接百度云api实现图像无损放大的功能。经过...
帝国cms默认只有上次登录时间与ip,没有一个记录清单,所以今天,我们分享这个帝...
帝国CMS自带的搜索功能虽然强大,但也有很强的局限性 -- 必须关键词完全匹配...
下载鸥开发了这款帝国cms封禁ip插件,自动记录访问情况,让我们可以更快的识别...
用户体验是我们的需求,百度蜘蛛的认可更是我们的需求。毕竟,没有收录排名,何来...
使用帝国cms的企业用户、新闻资讯类站点的用户很多,此类站点很多时候需要有...
一直没看到好用的帝国cms在线考试插件,所以自己开发了一款。在线考试插件用...
采集站的必备资源是自动审核,要做到日收录也离不开定时发布。而本插件的自动...