wade king
wade king

Reputation: 363

how to set cookies during vuejs post

I am trying to send post data to a django Restful API using vuejs. here is the code I have so far:

<script>
import axios from 'axios'
import VueCookies from 'vue-cookies'
//3RD ATTEMPT
VueCookies.set("csrftoken","00000000000000000000000000000000");
// @ is an alias to /src
export default {
  name: "Signup",
  components: {},
  data: () => {
  },
  methods: {
    sendData(){
        // 2ND ATTEMPT
        // $cookies.set("csrftoken", "00000000000000000000000000000000");
        axios({
            method: 'post', //you can set what request you want to be
            url: 'https://localhost:8000/indy/signup/',
            data: {
                csrfmiddlewaretoken: "00000000000000000000000000000000",
                first_name: "wade",
                last_name: "king",
                email: "wade%40mail.com",
                password1: "05470a5bfe",
                password2: "05470a5bfe"
            },
            // 1ST ATTEMPT
            // headers: {
            //     Cookie: "csrftoken= 00000000000000000000000000000000"
            // },
            withCredentials: true
        })
    }
  }
</script>

I have a button which executes the sendData() method on a click. The code uses the axios library to send a post request to the django API running on http://localhost:800/indy/signup/

The problem with just sending a post request to the API is that it will get blocked in order to prevent Cross Site Response Forgery (CSRF), I dont quite understand CSRF but I know if the csrftoken is set as a cookie and has the same value as the csrfmiddlewaretoken then the post should go through to the API.

You can see my attempts to set the cookie in the code I provided

1ST ATTEMPT)

headers: {
    Cookie: "csrftoken= 00000000000000000000000000000000"
},

Here I'm trying to set the cookie directly in the header. When I click send I get an error in my browser console saying refused to set unsafe header "Cookie"

2ND ATTEMPT)

$cookies.set("csrftoken", "00000000000000000000000000000000");

Here I'm trying to set the cookie using the vue-cookies module. When i click send I get the following error, net::ERR_SSL_PROTOCOL_ERROR

3RD ATTEMPT)

VueCookies.set("csrftoken","00000000000000000000000000000000");

Here I'm trying to set a global cookie using the vue-cookies module. When I click send I get the same error as attempt 2

IMPORTANT: However when I send post data to the API from my terminal using the following curl command, it works perfectly

curl -s -D - -o /dev/null \
-H 'Cookie: csrftoken= 00000000000000000000000000000000' \
--data 'csrfmiddlewaretoken=00000000000000000000000000000000&first_name=wade&last_name=king&email=wade%40mail.com&password1=05470a5bfe&password2=05470a5bfe' \
http://localhost:8000/indy/signup/

my main question is How can I replicate this curl request using vuejs? I've looked all over on line and none of the tutorials deal with setting cookies.

Upvotes: 2

Views: 6143

Answers (1)

wade king
wade king

Reputation: 363

I posted this question some time ago, I have managed to work around it by running the vue frontend on the same network as the django backend. Follow this tutorial for instructions: integrating vuejs and django Once I had the application set up I was able to set the cookies much more cleanly using :

axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"

Here is my login page for example

<template>
    <div class = "container">
        <h2>Sign In</h2>
        <b-form v-on:submit.prevent="submit()">
            <b-form-group id="signin" label="">
                <!-- dynamic error message -->
                <p class="loginErr" v-if="logErr">Incorrect Username or Password</p>
                <b-form-input 
                    id="signin-email"
                    v-model="username"
                    placeholder="Email"
                    required
                ></b-form-input>

                <b-form-input 
                    id="signin-password"
                    v-model="password"
                    placeholder="Password"
                    required
                    type="password"
                ></b-form-input>



            </b-form-group>

            <b-button v-if="!loading" type="submit" variant="primary">Submit</b-button>
            <b-spinner v-if="loading"></b-spinner>
        </b-form>

    </div>
</template>
<script>
import axios from 'axios'
import Vue from 'vue'
export default {

    data: ()=>{
        return{
            loading: false,
            logErr: false,
            username:'',
            password:'',
            next: '%2Findy%2Fprofile%2F'
        }
    },
    created: function(){

    },
    methods: {
        submit(){
            var vm = this;
            vm.loading = true;
            var dataStr = 'username='+vm.username+'&password='+vm.password

            //set the csrf tokens so django doesn't get fussy when we post
            axios.defaults.xsrfCookieName = 'csrftoken'
            axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"

            axios.post('http://localhost:8000/api/signin/', dataStr)
                .then(function (response) {
                    vm.loading = false;
                    //determine if indy accepts the login request

                    var res = response.data
                    console.log(response.data)


                    if(!res.login){
                        vm.logErr = true;
                    }else{
                        vm.redirect('home');
                    }


                })
                .catch(function (error) {
                    //currentObj.output = error;
                });
        },
        redirect(path) {
            this.$router.push('/' + path);
        }
    }
}
</script>
<style>
.loginErr{
    color: orange;
}
</style>

Upvotes: 1

Related Questions