gpt4 book ai didi

python - 如何使用CSRF token进行跨域Ajax调用?

转载 作者:行者123 更新时间:2023-12-01 05:52:37 26 4
gpt4 key购买 nike

我的 Django 应用程序模板中有一个典型的登录表单(直接使用 Bootstrap,而不是通过某些插件):

  <form class="form-signin" method="post" action="/site_manager/login/" id="form-signin"> {% csrf_token %}
<h2 class="form-signin-heading">Please sign in</h2>
<div class="control-group">
<label class="control-label" for="login">Login:</label>
<div class="controls">
<input size="50" name="username" id="username" required="true" type="text" class="form-control" placeholder="Login" intermediateChanges=false>
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">Password:</label>
<div class="controls">
<input size="50" name="password" id="password" required="true" type="password" class="form-control" placeholder="Password" intermediateChanges=false>
</div>
</div>
<button name="submit" id="submit" value="Log in" type="submit" class="btn btn-primary pull-right">Sign in</button>
</form>

这里是通过 requests module 进行远程认证的对应 View :

def login_view(request):
if request.POST:
username = request.POST.get('username')
password = request.POST.get('password')
headers = {'content-type': 'application/json', 'username':username, 'password':password}
r = requests.get(remote_server_url, auth=(username, password), headers=headers)
if r.status_code == 200:
user = authenticate(username=username, password=password)
if user == None:
user = User.objects.create_user(username.encode('ascii', 'ignore'), "", password)
user = authenticate(username=username, password=password)
login(request, user)
request.session.set_expiry(0)
return HttpResponseRedirect('<index_page>')
else:
# redirects back to login page with some error message

登录成功后,我可以使用 Javascript 查询 CSRF token ,如所述 here ,我的计划是对远程服务器进行 Ajax 调用(通过 SSL)以用于其他目的(例如,RESTful 查询)。正如上面的代码所示,该服务器使用基本身份验证。所以我想在每个Ajax调用的 header 中设置CSRF token ,但这不遵循同源原则:

var csrftoken = $.cookie('csrftoken'); // using the jQuery Cookie plugin

$.ajaxSetup({
headers: {
'Authorization': "Basic XXXXX"
}
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
});

$.ajax({
type: "GET",
dataType: "jsonp",
url: remote_server_url+'/api/v1/someRESTfulResource/',
contentType: 'application/json',
success: function(data){
// some operations with data
}

});

Ajax调用和身份验证中使用的remote_server_url是相同的,并且它不与Django应用程序共享相同的域。据我所知,这是一个安全风险。出于同样的原因,我也不想在 Javascript 代码中提供纯文本密码。如何使用用户凭据安全地对远程服务器进行 Ajax 调用?

最佳答案

我在我想用 django 进行 Ajax POSTS 的页面的 Javascript 初始化中执行此操作:

$(document).ajaxSend(function(event, xhr, settings) {

function sameOrigin(url) {
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
// or any other URL that isnt scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
function safeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", '{{ csrf_token }}');
}
});

我不记得在哪里找到它,但是使用它后我可以像这样执行 Ajax 帖子:

$.post("{% url 'foo' %}", "data="+myjson, function(data) {
if(data['result']=="ok") {
window.location.replace('{% url "bar" %}');
} else {
alert("Data Err!");
}
}).error(function() {
alert("Ajax error!");
});

关于python - 如何使用CSRF token进行跨域Ajax调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19771003/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com