понедельник, 31 октября 2011 г.

django: пример Ajax-аутентификации


В данной статье описывается пример реализации 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 %}

Комментариев нет:

Отправить комментарий

Если Вы нашли ошибку у автора, у Вас есть вопрос или просто хотите поделиться чем-то полезным, то пишите - не стесняйтесь..