Django AJAX调用解密接口返回HTML页面而非JSON响应如何解决
问题修复方案
核心出错点
- 前端AJAX请求的
url参数为空,默认请求当前页面路由,对应视图直接返回了页面HTML - Django 3.1及以上版本已完全废弃
request.is_ajax()方法,该判断条件永远不成立,代码始终走返回HTML的分支 - 后端用的是函数视图,不存在
self实例对象,调用self.nounce等属性会直接抛出异常,触发错误页返回HTML - AES-CTR模式加解密必须使用同一个nonce,你加密生成的nonce没有和密文一起存储,前端发起解密请求时也没有携带nonce参数,解密逻辑本身无法正常运行
- 代码存在笔误与逻辑漏洞:解密后的内容变量名错写为
mwssage,最终返回的还是未解密的原始message,就算流程走通也拿不到明文
修复代码
前端调整
首先你需要在存储加密消息时,把加密生成的nonce和密文一起存在数据库,chat:history接口返回的每条消息要同时携带message(密文)和nonce两个字段。
function loadMessage() { fetch("{% url 'chat:history' chatgroup.id %}") .then(response => response.json()) .then(data => { for (let msg of data) { const message = msg.message; const nonce = msg.nonce; $.ajax({ type: 'GET', // 替换为你解密接口对应的路由地址 url: "{% url 'chat:decrypt' %}", data: { message: message, nonce: nonce }, success: function(response){ broadcastMessage(response.message, msg.username, msg.date_created) } }) } }) }
后端views.py调整
from django.http import JsonResponse from Crypto.Cipher import AES from base64 import b64decode # 固定密钥建议存在settings.py中,不要硬编码在业务代码里 DECRYPT_KEY = b'\xa8|Bc\xf8\xba\xac\xca\xdc/5U0\xe3\xd6f' def decrypt(request): # 只有同时携带message和nonce参数的GET请求才走解密逻辑 if request.method == 'GET' and 'message' in request.GET and 'nonce' in request.GET: message = request.GET.get('message') nonce_ = request.GET.get('nonce') # 解密逻辑 nonce = b64decode(nonce_) ct = b64decode(message) cipher = AES.new(DECRYPT_KEY, AES.MODE_CTR, nonce=nonce) plain_msg = cipher.decrypt(ct).decode() # 返回解密后的明文 return JsonResponse({'message': plain_msg}) # 普通页面请求返回HTML return render(request, 'chat/room.html')
注:需要新增对应的解密路由配置,指向上面的
decrypt视图,和前端ajax的url对应即可。
内容的提问来源于stack exchange,提问作者Byron Jonnes
相关产品推荐
相关产品推荐

