0

I'm trying to implement the login feature using django and vue.js. But I got an error "CSRF cookie not set" when sending the post request. I checked that I could get the csrftoken correctly by seeing the developer tools.

Below is the code of login.vue

<template>
  <div class="hello">
    <div class="title-color">This is a Login page.</div>
    <div class="form-container">
        <form v-on:submit.prevent="getCSRF">
          <h2>Add User</h2>
          <div class="form-group">
            <label class="label">username</label>
            <input class="input" type="text" v-model="username" /><br>
          </div>
          <div class="form-group">
            <label class="label">password</label>
            <input class="input" type="text" v-model="password" /><br>
          </div>
          <button class="button" type="submit">Submit</button>
        </form>
    </div>
  </div>
</template>

<script>
import axios from "axios";

axios.defaults.xsrfHeaderName = 'x-csrftoken'
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.withCredentials = true;

export default {
  name: "LoginView",
  props: {
    msg: String,
  },
  data() {
    return {
      username: "",
      password: "",
      csrftoken: "",
    };
  },
  mounted() {
  },
  methods: {
    getCSRF() {
      axios({
        method: "get",
        url: "http://127.0.0.1:8000/csrf/",
        auth: {
          username: "cannot show",
          password: "cannot show",
        },
      }).then((response) => {
        this.csrftoken = response.headers['x-csrftoken'];
        console.log("token is ", this.csrftoken);
        axios({
          method: "post",
          url: "http://127.0.0.1:8000/login/",
          data: {
            username: this.username,
            password: this.password,
          },
          headers: {
            'X-Csrftoken': this.csrftoken,
          },
          auth: {
            username: "Cannot show",
            password: "Cannnot show",
          },
        }).then((response) => {
          console.log(response);
        })
      })
    },
  }
};
</script>

Below is the views.py

def loginView(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(request, username=username, password=password)
    if user is not None:
        login(request, user)
        response = JsonResponse({'detail': 'OK'})
        return response
    else:
        return Response("Invalid username or password.")
    
@ensure_csrf_cookie
def getToken(request):
    response = JsonResponse({'detail': 'csrf cookie set'})
    response['Access-Control-Expose-Headers'] = 'X-Csrftoken'
    response['x-csrftoken'] = get_token(request)
    return response

I could set X-Csrftoken to the request headers correctly. However, I'm not sure how I can set the cookie.

3
  • It seems that axios doesn't send cookies by default. Could you try to use withCredentials=true option like pointed out in this post ? Could you check the network panel of the browser window if cookies are sent back to the server? Commented Dec 14, 2023 at 10:49
  • Thank you for the comment. In login.vue, I've already added axios.defaults.withCredentials = true But it doesn't solve the problem. I found that the cookie that I send was blocked because it had "SameSite=Lax". I'll try to fix it and will write the update. Commented Dec 18, 2023 at 5:39
  • I added response.set_cookie('key', 'value', secure=True, samesite='None') to the loginView. and SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True SESSION_COOKIE_SAMESITE = None CSRF_COOKIE_SAMESITE = None to the setting.py (django) But it didn't solve the problem. Commented Dec 18, 2023 at 10:04

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.