schel4ok
schel4ok

Reputation: 684

Csrf token in vue component

I have Laravel 5.3 project with Vue.js integrated and I want to use CSRF-TOKEN in my form. Form html code is in Vue component file in

resources / assets / js / bootstrap.js

I have this:

Vue.http.interceptors.push((request, next) => {
    request.headers.set('X-CSRF-TOKEN', MyApp.csrfToken);
    next();
});

then I have main vue file /resources/assets/js/app.js:

require('./bootstrap');
Vue.component('callbackwindow', require('./components/callbackwindow.vue'));

const app = new Vue({
    el: '#app',
    data: { },
});

then in Vue file I need to use csrf_field, but I don't know how to get it there, because standard php csrf_field() is not rendered inside Vue component and I don't know how to import MyApp.csrfToken.

<template>
<div class="modal fade" >
    <form @submit.prevent="submitForm" name="callback" method="POST" action="/" role="form" class="form-horizontal" enctype="multipart/form-data">
    {!! csrf_field() !!}
    ...form code here...
    </form>
</div>
</template>
<script>
    export default {    }
</script>

Is it possible to import MyApp.csrfToken variable from here into my Vue template file?

Upvotes: 7

Views: 44304

Answers (6)

Make a token then assign it

<script>
export default {
    data() {
        return {
            token: '',

        }
    },
 async created() {
        this.token = document.querySelector('meta[name="csrf-token"]').getAttribute('content')
}
</script>

I was using Iview so I used it like that

:headers="{'x-csrf-token' : token}"

But normally you will use

v-bind:value="token"

Upvotes: 0

Murad
Murad

Reputation: 1162

If you have written meta tags for csrf token in the master template then try this.

<template>
      <form action = "/user/checkout" method="POST">
        <input type="hidden" name="_token" v-bind:value="csrf">
       ....
      </form>
</template>

In the script tag of the component:

 <script>
    export default{

        data(){
          return {
            //csrf token
             csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
       }
    }

    </script>

Upvotes: 10

SAIF ALI
SAIF ALI

Reputation: 71

Do this in blade:

<Example-component csrf="{{csrf_token()}}"></Example-component>

Do this in Vue Component:

In form
<input type="hidden" name="_token" v-bind:value="csrf">
In Script
export default {
        props: ['csrf', 'oldName']

   }

Upvotes: 3

Yaser Khahani
Yaser Khahani

Reputation: 705

As an alternative ways:

1- Get the token from meta tag with csrf-token name inside of <head>:

$('meta[name="csrf-token"]').attr('content')

2- Pass it as a prop to your Vue component:

<your-component :csrf-token="{{ csrf_token() }}"></your-component>

Upvotes: 14

koalaok
koalaok

Reputation: 5760

I had same Issue and I solved like this. I'm not very proud because I'm making dirty the global scope

By adding the following:

in app.blade.php

<script>
 var Laravel = {
            'csrfToken' : '{{csrf_token()}}'
        };

in my whatever component/child component MyComponent.vue:

<form method="POST" action="/my/path" class="pull-right">
    <input type="hidden" name="_token" :value="csrf">       
    <input class="btn" type="submit" value="Modify" />
</form>


<script>
    export default{
        data() {
            return {
                csrf: "",
            }
        },
        mounted() {
            this.csrf = window.Laravel.csrfToken;
        }
    }
</script>

Upvotes: 0

Rwd
Rwd

Reputation: 35200

One way you could define you csrf token would be to add the following to your head section of your main blade file:

<script>
    var MyApp = {
        csrfToken: "{{ csrf_token() }}"
    }
</script>

Alternatively, you could use import something like the cookie library and use the xsrf token instead.

with npm:

npm install cookie

with yarn:

yarn add cookie

Then in your bootstrap.js file:

import cookie from "cookie";


Vue.http.interceptors.push((request, next) => {
    request.headers.set('X-XSRF-TOKEN', cookie.parse(document.cookie)['XSRF-TOKEN']);
    next();
});

Hope this helps!

Upvotes: 1

Related Questions