Django: login_required on ajax call

梦想与她 提交于 2019-12-05 20:11:35

问题


I am trying to authenticate user on ajax post but doesn't work. Here what I have done

settings.py

LOGIN_URL = '/accounts/login/'
LOGIN_REDIRECT_URL = '/'

Template

<script>
  $('.btn-request').click(function(){
        var button = this;
        $.ajax({
                 type: "POST",
                 url: "{% url 'like' %}",
                 data: {'tutorial_id': $(this).attr('name'), 'csrfmiddlewaretoken': '{{csrf_token}}'},
                 dataType: "json",
                 success: function(json) {
                    toastr.success(json.message);

                  },
                  error: function(rs, e) {
                        alert(rs.responseText);
                  }
            });
      })
  </script>

urls.py

url(r'^like/$', 'apps.quotation.views.like', name='like'),

views.py - try 1

@login_required
def like(request):
        vars = {}
        if request.method == 'POST':
            response_dict = {}

            if not something:
                response_dict.update({'message': "Requested" })
            else:
                response_dict.update({'message': "You have already requested" })

        return HttpResponse(simplejson.dumps(response_dict),
                        mimetype='application/javascript')

views.py - try 2

def like(request):
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/accounts/login')
    else:
        vars = {}
        if request.method == 'POST':
            response_dict = {}
            if not something:
                response_dict.update({'message': "Requested" })
            else:
                response_dict.update({'message': "You have already requested" })

        return HttpResponse(simplejson.dumps(response_dict),
                        mimetype='application/javascript')

Runserver log

[05/Mar/2014 05:19:16] "POST /like/ HTTP/1.1" 302 0
[05/Mar/2014 05:19:16] "GET /accounts/login/?next=/like/ HTTP/1.1" 200 5610

What I am missing?


回答1:


Instead of :

if not request.user.is_authenticated():
   return HttpResponseRedirect('/accounts/login')

return json response :

if request.user.is_authenticated():
    ## write your code...
    jsonr = json.dumps({ 'authenticated': True })
    return HttpResponse(jsonr, mimetype='application/json')
else:
    jsonr = json.dumps({ 'authenticated': False })
    return HttpResponse(jsonr, mimetype='application/json')

And At your ajax success response , if not authenticated then redirect to login using windows.location .

OR you can write decorator : Django authentication and Ajax - URLs that require login




回答2:


When I want to check that when an Ajax call is made the user is logged in, here is what I use:

from functools import wraps
from django.core.exceptions import PermissionDenied

def ajax_login_required(view):
    @wraps(view)
    def wrapper(request, *args, **kwargs):
        if not request.user.is_authenticated():
            raise PermissionDenied
        return view(request, *args, **kwargs)
    return wrapper

raise PermissionDenied will cause a 403 status code to be returned to the client. Otherwise, if you use the @login_required decorator or perform manually a redirect to a form, what the Ajax call sees as a response is something that makes sense to a human being but not something that makes sense to an Ajax call.




回答3:


I am not sure whether it's an elegant solution but I made it to work as suggested by Priyank Patel

<script>
  $('.btn-request').click(function(){
        var button = this;
        $.ajax({
                 type: "POST",
                 url: "{% url 'like' %}",
                 data: {'tutorial_id': $(this).attr('name'), 'csrfmiddlewaretoken': '{{csrf_token}}'},
                 dataType: "json",
                 success: function(json) {
                    if(json.not_authenticated) {

                      window.location.replace("/accounts/login");
                    }
                    else {
                    toastr.success(json.message);
                    }  
                  },
                  error: function(rs, e) {
                    alert(rs.responseText);
                  }
            });
      })
  </script>

views.py

def like(request):
    response_dict = {}
    if request.user.is_authenticated():
        if request.method == 'POST':
            if not something:
                response_dict.update({'message': "Requested" })
            else:
                response_dict.update({'message': "You have already requested" })

        return HttpResponse(simplejson.dumps(response_dict),
                        mimetype='application/javascript')
    else:
        response_dict.update({'message': "Login please",'not_authenticated':True  })
        return HttpResponse(simplejson.dumps(response_dict),
                        mimetype='application/javascript')


来源:https://stackoverflow.com/questions/22196422/django-login-required-on-ajax-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!