Search code examples
htmljquerydjangoajaxcsrf-token

JsonResponse incorrectly sending me to a new url


I'm getting a very odd error. I'm attempting to make a login form that will check to make sure the username/password combination is correctly. After taking in the username and password, the views.py function takes in the information and authenticates. If it turns out the username/password combo is no good, it should return blanks for the data = {"username": "", "pass":""} and returned to the ajax call which should then show a text error of "Username and Password combo is incorrect".

When I put in a non existing email/username value or an incorrect password for an existing email/uername it will redirect me to an entirely new url ending in /login_user/ and displays {"username": "", "pass":""} as text in some new html file.

Absolutely no idea why this is occurring, an error I'm getting in console is

Resource interpreted as Document but transferred with MIME type application/json: "http://localhost:8000/rab/login_user".

And the command prompt is giving error of this:

[05/Aug/2020 11:15:54] "POST /rab/login_user HTTP/1.1" 200 28
Forbidden (CSRF token missing or incorrect.): /rab/login_user

urls.py

path('login_user', views.login_user, name='login_user'),

login.js

$(document).ready(function() {
                    
    $("#login-btn").on("click", function(e){
        var tk = $(this).attr("data-token");
        let username = $("#login-username").val();
        let pw = $("#login-pw").val();
        let data = $(this).serialize();

        $.ajax({
            url: $('#log-form').attr("action"),
            type: 'POST',
            dataType: 'json',
            contentType: false,
            data: {
                'csrfmiddlewaretoken': tk, 'username': username, 'pass':pw
            },
            success: function(data) {
                if (data.username == "") {
                    console.log('Got here');
                    $(".login-error-messages").text("Username and password combination was incorrect!").fadeIn().delay(10000).fadeOut();
                } else {
                    sessionStorage.setItem("restaurantID", 1);
                    sessionStorage.setItem("userID", 1);
                }
            },
        });
    });

views.py

@require_http_methods(['POST'])
def login_user(request):
    username = request.POST['username']
    password = request.POST['pass']
    user = authenticate(username = username, password = password)
    if (user is not None):
        login(request, user)
        return redirect_user(user.role.id)
    else:
        data = {'username':"",'pass':""}
        return JsonResponse(data)    

login.html

                 <form class="login" id = "log-form" method="POST" action="login_user">
                    {% csrf_token %}
                        <p class="form-title">
                            User login
                        </p>

                        <div class="wrap-input">
                            <input id = "login-username" class="input" type="email" name="username" placeholder="Username (Email)" required>
                        </div>

                        <div class="wrap-input">
                            <input id = "login-pw" class="input" type="password" name="pass" placeholder="Password" required>
                        </div>
                        
                        <div class="container-form-btn">
                            <input type=Submit id="login-btn" class="form-btn" value="Login" data-token = "{{ csrf_token }}">
                            <!--<button id="login-btn" class="form-btn" type="button">
                                Sign in
                            </button>-->
                        </div>
                </form>
                <p><div class="login-error-messages" style="display:none;"></div></p>

Solution

  • you have an input type submit, then this will process the form action before the Ajax, try change type to button.

    <input type="button" id="login-btn" class="form-btn" value="Login" data-token = "{{ csrf_token }}">
    

    I hope this solves your problem.

    Edited

    The "submit" type will send the form elements to the action page. The "button" type don't.

    If for any reason you need to put a submit button, you need to use the function prevent preventDefault function on submit event.

    $("#log-form").submit(function(event){
            event.preventDefault();
    });