1
votes

I have a django server which acts as an API (i.e. listens to requests and returns data ONLY), and I want this API to be accessible only to authenticated users. I read about the django authentication system, and tried to implement it according to the documentation (https://docs.djangoproject.com/en/2.0/topics/auth/default/).

I wrote a small web-page just to test the authentication - login was successful (server was able to authenticate and login the user), but when attempting to reach a restricted view I have no access, and the request.user received is an AnonymousUser instead of the logged in user.

I am using Python 3.6.5 and Django 2.0.4

Server code:

@csrf_exempt
def dologin(request):
    username = request.POST.get('username')
    password = request.POST.get('password')
    if not username or not password:
        return HttpResponse('missing username or password', status=400)
    user = authenticate(request, username=username, password=password)
    if user is not None:
        login(request, user)
        return HttpResponse(user)
    else:
        return HttpResponse('bad credentials', status=422)

def dologout(request):
    logout(request)
    return HttpResponse('success')

@login_required()
def testAccess(request):
    return HttpResponse('ok')

def checkUser(request):
    u = "anonymous" if not request.user.is_authenticated else request.user.username
    return HttpResponse(u)

Client code:

<label>username:</label>
<input type="text" id="uin"/>
<label>username:</label>
<input type="text" id="pin"/>
<button id="inbtn">login</button>
<button id="outbtn">logout</button>
<button id="test">test access</button>
<button id="check">check user</button>

<div id="res"></div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" type="text/javascript"></script>
<script>
    $("#inbtn").click(function(){
        u = $("#uin").val();
        p = $("#pin").val();
        d = {username: u, password: p};
        $.post("http://10.0.0.9:8000/login/", d, function(data){
            $("#res").html(data);
        }).fail(function(xhr, status, error){
            $("#res").html(xhr.responseText + " - " + xhr.status);
        });
    });

    $("#outbtn").click(function(){
        $.get("http://10.0.0.9:8000/logout/", function(data){
            $("#res").html(data);
        }).fail(function(xhr, status, error){
            $("#res").html(xhr.responseText + " - " + xhr.status);
        });
    });

    $("#test").click(function(){
        $.get("http://10.0.0.9:8000/testaccess/", function(data){
            $("#res").html(data);
        }).fail(function(xhr, status, error){
            $("#res").html(xhr.responseText + " - " + xhr.status);
        });
    });

    $("#check").click(function(){
        $.get("http://10.0.0.9:8000/checkuser/", function(data){
            $("#res").html(data);
        }).fail(function(xhr, status, error){
            $("#res").html(xhr.responseText + " - " + xhr.status);
        });
    });
</script>

(I'm running everything locally, that's why I use 10.0.0.9 which is my pc's ip)

As i wrote before - after a successful login, clicking 'test access' results in a 404 response, and clicking 'check user' returns 'anonymous' (and by debugging the server I know the user is indeed AnonymousUser)

1
Have you enabled sessions? I don't recall where it specified this, but I think you might run into this issue if you don't have sessions enabled...because Django only knows you've logged in from the session cookie. - user
yes, sessions is enabled (by default btw) - dorbs

1 Answers

1
votes

I suspect your problem is with the session data.

After authentication and login, the user is set within a single django session. A HTTP cookie (per default named sessionid) will be set with an session number.

For every subsecuent request you need to also pass sessionid to the server, so that the server can identify which user this new request belongs to.

You should read up on how to get the sessionid cookie after login and how to send that same sessionid along with the new requests.