В данной статье описывается пример реализации ajax-аутентификации в django.
На стороне клиента используется js-фреймворк Dojo. Ничто не мешает взять любой другой, например jquery.
Итак приступим:
1. определяем специальный view для обработки ajax-запросов (используем только POST)
#views.py
from django.contrib.auth.forms import AuthenticationForm
@csrf_protect #предварительно в settings.py надо подключить соответствующее moddleware
@never_cache
def ajax_login(request, template_name='registration/login.html',
redirect_field_name=REDIRECT_FIELD_NAME,
authentication_form=AuthenticationForm,
current_app=None, extra_context=None):
logger = logging.getLogger(__name__)
manipulator = AuthenticationForm(request)
redirect_to = request.REQUEST.get(redirect_field_name, '')
if request.method == "POST":
form = authentication_form(data=request.POST)
if form.is_valid():
netloc = urlparse.urlparse(redirect_to)[1]
auth_login(request, form.get_user())
if request.session.test_cookie_worked():
request.session.delete_test_cookie()
logger.error('SUCCESS')
return HttpResponse(simplejson.dumps("OK"))
else:
logger.error('FAILED')
return HttpResponse(simplejson.dumps("FAIL"))
else:
return HttpResponseRedirect('/');
form = authentication_form(request)
request.session.set_test_cookie()
current_site = get_current_site(request)
context = {
'form': form,
redirect_field_name: redirect_to,
'site': current_site,
'site_name': current_site.name,
}
context.update(extra_context or {})
return render_to_response(template_name, context,
context_instance=RequestContext(request, current_app=current_app))
2. вставим в соответствие конкретному url определенную выше view
from my_auth_app.views import ajax_login
urlpatterns += patterns('',
url(r'^login/ajax', ajax_login),
)
3. Описываем шаблон формы и клиентскую js-часть:
<script>
var sendLoginButton;
function sendLogin(){
dojo.xhrPost({
url: '/login/ajax/',
load:sendLoginCallback,
form: dojo.byId('loginForm'),
handleAs: "json",
error: function(response,ioArgs) {
dojo.byId("messagestatus").innerHTML = "Попробуйте еще раз!";
dojo.byId("loginForm").style.display = "yes";
});
dojo.byId("loginForm").style.display = "none";
dojo.byId("messagestatus").innerHTML = "Проверка...";
}
function sendLoginCallback(type, data, evt) {
console.error(type);
console.error(data);
console.error(evt);
if (type == 'FAIL'){
dojo.byId("messagestatus").innerHTML = "Попробуйте еще раз!";
dojo.byId("loginForm").style.display = "";
}
else {
if (data == "false") {
dojo.byId("loginForm").style.display = "";
dojo.byId("messagestatus").innerHTML = "Your password or username is invalid";
dojo.disconnect(sendLoginButton, 'onclick', 'sendLogin');
var anim = dojo.lfx.html.highlight("messagestatus", [255, 0, 0], 200).play(100);
dojo.connect(anim, "onEnd", function() { dojo.connect(sendLoginButton, 'onclick', 'sendLogin'); });
}
else {
window.location="/";
}
}
}
function init(){
console.log(document.cookie);
sendLoginButton = dojo.byId('loginButton');
var loginForm = dojo.byId('loginForm');
if(loginForm){
loginForm.onsubmit = function() { return false; }
dojo.connect(sendLoginButton, 'onclick', 'sendLogin');
}
}
dojo.addOnLoad(init);
</script>
<div id="messagestatus"></div>
{% if user.is_authenticated %}
<p id="welcome">Хелло, {{user.username}}</p>
{% else %}
<form method="post" id="loginForm" class="blocks">
{%if form.errors %}
Неудачный вход.
{% endif %}
<label for="id_user">Ник:</label> {{ form.username }}
Ошибка:{{form.username.errors}}
Пояснение:{{ form.username.help_text }}
<label for="id_password">Пароль:</label> {{ form.password }}
Ошибка:{{form.password.errors }}
Пояснение:{{ form.password.help_text }}
<input id="loginButton" class="large button" type="submit" value="ВОЙТИ" />
</form>
{% endif %}