You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Django应用:如何阻止用户通过浏览器URL访问GET接口数据

解决Django中阻止浏览器直接GET访问、区分代码调用与浏览器请求的问题

嘿,这个场景我太熟悉了!只用sessionid确实没法区分请求是来自浏览器手动输入URL,还是代码/前端AJAX的合法调用——毕竟只要会话有效,两种请求都会带上session凭证。下面给你几个实用的解决方案,你可以根据自己的业务场景选择:

方案1:检查自定义请求头(最推荐)

核心思路是让合法的代码/前端调用主动携带一个自定义请求头,而浏览器直接输入URL时不会包含这个头。在视图里验证这个头的存在和正确性,就能拦截非法访问。

后端视图代码

from django.http import HttpResponseForbidden
from django.http import JsonResponse

def protected_data_view(request):
    if request.method == 'GET':
        # 检查自定义请求头,这里用X-Requested-By作为示例,你可以自定义名称
        valid_header = request.META.get('HTTP_X_REQUESTED_BY')
        if valid_header != 'Your-App-Client':
            return HttpResponseForbidden("Direct browser access is not allowed.")
        
        # 这里处理正常的GET请求逻辑,返回数据
        return JsonResponse({"data": "your protected content"})
    
    # 处理其他请求方法(如POST)
    # ...

代码调用示例(比如用requests库)

import requests

url = "http://your-domain.com/protected-data/"
headers = {
    "X-Requested-By": "Your-App-Client",
    "Cookie": "sessionid=your-session-id"  # 如果需要会话认证的话
}
response = requests.get(url, headers=headers)

前端AJAX示例(fetch)

fetch('/protected-data/', {
    method: 'GET',
    headers: {
        'X-Requested-By': 'Your-App-Client',
        'X-CSRFToken': document.cookie.split('; ').find(row => row.startsWith('csrftoken=')).split('=')[1]
    }
})
.then(response => response.json())
.then(data => console.log(data));

这个方案的优势是可靠性高,普通用户很难在浏览器地址栏直接添加自定义请求头,足以应对大部分场景。

方案2:检查X-Requested-With头(适配AJAX场景)

如果你的请求主要来自前端AJAX调用,可以利用传统AJAX请求会携带的X-Requested-With: XMLHttpRequest头。注意:Django 3.1之后request.is_ajax()方法已被弃用,需要手动检查这个头。

from django.http import HttpResponseForbidden
from django.http import JsonResponse

def ajax_protected_view(request):
    if request.method == 'GET':
        is_ajax_request = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
        if not is_ajax_request:
            return HttpResponseForbidden("Only AJAX requests are allowed.")
        
        # 正常处理请求
        return JsonResponse({"data": "ajax-only content"})

这个方案适合纯前端AJAX调用的场景,但要注意:如果用户用开发者工具手动添加这个头,也能绕过拦截,适合对安全性要求不是极高的内部系统。

方案3:检查Referer头(辅助验证,不单独使用)

通过检查请求的Referer头,判断请求是否来自你的站点内部(比如从你的前端页面跳转过来)。但这个方法局限性很大,因为Referer可能被浏览器或安全工具屏蔽,也容易被伪造,所以建议只作为辅助验证手段。

from django.http import HttpResponseForbidden
from django.http import JsonResponse

def referer_protected_view(request):
    if request.method == 'GET':
        referer = request.META.get('HTTP_REFERER')
        # 验证Referer是否来自你的域名
        if not referer or not referer.startswith('https://your-domain.com'):
            return HttpResponseForbidden("Direct access not allowed.")
        
        # 处理请求
        return JsonResponse({"data": "referer-validated content"})

额外注意事项

  • 以上方法都无法完全阻止技术熟练的用户伪造请求,如果需要更高安全性,可以结合API密钥、OAuth2等认证机制。
  • 如果你是前后端分离项目,需要确保跨域配置允许自定义请求头的传递。
  • 测试时记得分别用浏览器直接访问URL(应该返回403)和合法代码/前端调用(应该正常返回数据)验证效果。

内容的提问来源于stack exchange,提问作者Ramesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:02:48