Laravel CSRF Field in Vue Component

2019-07-02 00:11发布

I would like to ask how can I add the csrf_field() in my vue component. The error is

Property or method "csrfToken" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.

Here's the code:

<script>
export default {
  name: 'create',
  data: function(){
    return {
        msg: ''
    }
  },
  props:['test']
}
</script>
<template>
  <div id="app">
    <form action="#" method="POST">
      {{csrfToken()}}
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" id="name" class="form-control"> 
      </div>
      <div class="form-group">
        <label for="location">Location</label>
        <input type="text" id="location" class="form-control"> 
      </div>
      <div class="form-group">
        <label for="age">Age</label>
        <input type="number" id="age" class="form-control"> 
      </div>
      <div class="form-group">
        <input type="submit" class="btn btn-default"> 
      </div>
    </form>
  </div>
</template>

6条回答
Evening l夕情丶
2楼-- · 2019-07-02 00:45

Came across this problem whilst building multiple forms in a vue v-for loop.

added to data;

csrf: document.head.querySelector('meta[name="csrf-token"]').content,

Added hidden form element

<input type="hidden" name="_token" :value="csrf" /> 
查看更多
再贱就再见
3楼-- · 2019-07-02 00:47

Try this:

<script>
export default {
  name: 'create',
  data: function(){
    return {
        msg: '',
        csrf: window.Laravel.csrfToken
    }
  },
  props:['test']
}
</script>

And in your markup just use

<input type="hidden" name="_token" :value="csrf" />

EDIT

Bit of a rabbit hole but, one great feature of Vue is that it can easily handle POST, PATCH, etc. requests using AJAX and the vue-resource extension. Instead of using a <form> here you can process this data using your Vue component. If you were to take this route, you can set default headers to send with each request no matter what method it is, so you can always send your CSRF token.

exports deafult{
 http: {
  headers: {
   'X-CSRF-TOKEN': window.Laravel.csrfToken
  }
 }
}
查看更多
【Aperson】
4楼-- · 2019-07-02 00:48

As I already wrote here, I would simply suggest to put this in your PHP file:

<script>
    window.Laravel = <?php echo json_encode(['csrfToken' => csrf_token()]); ?>
</script>

This way you're able to easily import your csrfToken from the JS part (Vue in this case).

Moreover, if you insert this code in your PHP layout file, you can use the token by any component of your app, since window is a JS global variable.

Source: I got the trick from this post.

查看更多
萌系小妹纸
5楼-- · 2019-07-02 00:49

if you look at the /resources/assets/js/bootstrap.js you will find these lines

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
   window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
 } else {
  console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
 }

I believe you are using axios for your requests. this means you need to add

<meta name="csrf-token" content="{{csrf_token}}">

in your <head> tag.

查看更多
劳资没心,怎么记你
6楼-- · 2019-07-02 00:58

Laravel version 5 or later

First you need to store your CSRF token in a HTML meta tag in your header:

<meta name="csrf-token" content="{{ csrf_token() }}">

Then you can add it to your script:

<script>
export default {
  name: 'create',
  data: function(){
    return {
        msg: '',
        csrf: document.head.querySelector('meta[name="csrf-token"]').content
    }
  },
  props:['test']
}
</script>

And in the template:

<template>
  <div id="app">
    <form action="#" method="POST">
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" id="name" class="form-control"> 
      </div>
      <div class="form-group">
        <label for="location">Location</label>
        <input type="text" id="location" class="form-control"> 
      </div>
      <div class="form-group">
        <label for="age">Age</label>
        <input type="number" id="age" class="form-control"> 
      </div>
      <div class="form-group">
        <input type="submit" class="btn btn-default"> 
      </div>
      <input type="hidden" name="_token" :value="csrf">
    </form>
  </div>
</template>
查看更多
等我变得足够好
7楼-- · 2019-07-02 01:03

I think you need to write it like this:

{{ crsf_token() }}

and not like this:

{{ csrfToken() }}

If that doesn't work, maybe try this:

{!! csrf_token !!}
查看更多
登录 后发表回答