Django Forbidden (CSRF token missing or incorrect.) in Ajax request

Viewed 623

I am trying to submit a form using an ajax request in Django. However, when I move the script I get the following error:

Forbidden (CSRF token missing or incorrect.): /home/post/like/ [03/Apr/2020 00:49:55] "POST /home/post/like/ HTTP/1.1" 403 2513

my js code:

$(document).ready(function (e) {
    $(document).on("click", "#likeBtn", function (e) {
        e.preventDefault();
        var pk = $(this).attr("value");
        $.ajax({
            type: "POST",
            dataType: 'json',
            url: $(this).attr("data-url"),
            data: {'id':pk, 'csrfmiddlewaretoken': '{{ csrf_token }}'},        
            success: function (response){
                $("#like-section").html(response['form'])
            },
            error: function(rs, e){
                console.log(rs.responeText);
            },
        });
    });
})

my view:

@login_required
def post_like(request):
    post = get_object_or_404(Post, id=request.POST.get('id'))
    is_liked = False
    user = request.user
    if post.likes.filter(id=user.id).exists():
        post.likes.remove(user)
        is_liked = False
    else:
        post.likes.add(user)
        is_liked = True
    context = {
        'post' : post,
        'is_liked': is_liked,
    }
    if request.is_ajax():
       html = render_to_string('home/posts/likes.html', context, request=request)
       return JsonResponse({'form':html})

But when I add the following script to the html file It works:

$(document).ready(function (e) {
    $(document).on("click", "#likeBtn", function (e) {
        e.preventDefault();
        var pk = $(this).attr("value");
        $.ajax({
            type: "POST",
            dataType: 'json',
            url: "{% url 'home:post-like' }",
            data: {'id':pk, 'csrfmiddlewaretoken': '{{ csrf_token }}'},        
            success: function (response){
                $("#like-section").html(response['form'])
            },
            error: function(rs, e){
                console.log(rs.responeText);
            },
        });
    });
})

I have managed to solved the error using the below format, however, I do not know if it is a safe way to do so.

my new form:

<form action="{% url 'home:post-like' %}" method="POST">
    {% csrf_token %}
    {% if is_liked %}
        <button type="submit" id="likeBtn" data-url="{% url 'home:post-like' %}" data-token="{{ csrf_token }}" name="post_id" value="{{ post.id }}" class="btn btn-sm">
            <span class="text-primary">
                <i class="fas fa-thumbs-down"></i> {{ post.likes.count }}
            </span>
        </button>
    {% else %}
        <button type="submit" id="likeBtn" data-url="{% url 'home:post-like' %}" data-token="{{ csrf_token }}" name="post_id" value="{{ post.id }}" class="btn btn-sm">
            <span class="text-primary">
                <i class="fas fa-thumbs-up"></i> {{ post.likes.count }}
            </span>
        </button>
    {% endif %}
</form>

my new js code:

$(document).ready(function (e) {
    $(document).on("click", "#likeBtn", function (e) {
        e.preventDefault();
        var pk = $(this).attr("value");
        var tk = $(this).attr("data-token")
        $.ajax({
            type: "POST",
            dataType: 'json',
            url: $(this).attr("data-url"),
            data: {'id':pk, 'csrfmiddlewaretoken': tk},        
            success: function (response){
                $("#like-section").html(response['form'])
            },
            error: function(rs, e){
                console.log(rs.responeText);
            },
        });
    });

I am wondering if this is a safe way to do this?

0 Answers
Related