3

I'm getting "CSRF Failed: CSRF token missing or incorrect." error while doing a POST request to a django api from my localhost machine.

My service on Angular2:

public login(user: any){
      const body = JSON.stringify(user);
      const headers = new Headers();
      headers.append('Content-Type', 'application/json');
      return this.http.post("http://127.0.0.1:8000/auth_api/login/", body, {
        headers: headers
      })
        .map((data: Response) => data.json())
    }

My settings on Django:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'corsheaders',
    'scrumboard',
    'auth_api'
]


MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ORIGIN_ALLOW_ALL = True

my LoginView API:

class LoginView(views.APIView):
@csrf_exempt
def post(self, request):
    user = authenticate(
        username=request.data.get("username"),
        password=request.data.get("password"))

    if user is None or not user.is_active:
        return Response({
            'status': 'Unauthorized',
            'message': 'Email or password incorrect'
        }, status=status.HTTP_401_UNAUTHORIZED)

    login(request, user)
    return Response(UserSerializer(user).data)  

and finally my login.component.html where i am sending to the username and password to the login function:

<div class="card-block">
              <h1>Login</h1>
              <p class="text-muted">Sign In to your account</p>
              <form [formGroup]="myForm" (ngSubmit)="onSignin(username.value, password.value)">
              <div class="input-group mb-1">
                <span class="input-group-addon"><i class="icon-user"></i></span>
                <input formControlName="username" type="text" id="username" class="form-control" placeholder="username" #username>
              </div>
              <div class="input-group mb-2">
                <span class="input-group-addon"><i class="icon-lock"></i></span>
                <input formControlName="password" type="password" class="form-control" placeholder="Password" #password>
              </div>
              <div class="row">
                <div class="col-6">
                  <button type="submit" [disabled]="!myForm.valid" class="btn btn-primary px-2">Login</button>
                </div>
              </div>
            </form>
            </div>

What am i missing here ?

ccr0x
  • 51
  • 5

2 Answers2

0

Might not be the issue but how is the password getting sent in your login function?

Try adding {% csrf_token %} below your <form... tag.

I'd hesitate to make if CSRF exempt since it introduces cross site request forgery vulnerability.

Here's some of my code on a registration page that works.

<form class="form-horizontal" method="post" style="align: center">
          {% csrf_token %}
          {{ reg_form.non_field_errors }}
...
Harry MW
  • 134
  • 1
  • 10
0

You may not have the CSRF token set at the point in time where you login if you haven't already interacted with your API server.

You want to decorate your post method so that it doesn't require the token, and then only check the token in response to other subsequent POST requests that actually return data...

from django.views.decorators.csrf import csrf_exempt

@method_decorator(csrf_exempt, name='dispatch') class LoginView(views.APIView): def post(self, request): ...

James Scheller
  • 235
  • 3
  • 9
  • I think I had this wrong. I updated the code above to reflect the issue as discussed here... https://stackoverflow.com/questions/27315592/csrf-exempt-does-not-work-on-generic-view-based-class to use the decorator syntax for a class-based view instead of a view function... – James Scheller Mar 29 '18 at 17:02