如何将 Laravel CSRF 令牌值传递给 vue

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39938284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 17:32:35  来源:igfitidea点击:

How to pass laravel CSRF token value to vue

laravelvue.jslaravel-5.3

提问by Pathros

I have this form where the user should only type text inside a text area:

我有这个表单,用户应该只在文本区域内输入文本:

            <form action="#" v-on:submit="postStatus">{{-- Name of the method in Vue.js --}}
                <div class="form-group">
                    <textarea class="form-control" rows="5" maxlength="140" autofocus placeholder="What are you upto?" required v-model="post"></textarea>
                </div>
                <input type="submit" value="Post" class="form-control btn btn-info">

                {{ csrf_field() }}

            </form>

Then, I have this script code where I am using vue.js with ajax in order to pass that text into a controller and eventually save it into the database:

然后,我有这个脚本代码,我在其中使用 vue.js 和 ajax,以便将该文本传递到控制器并最终将其保存到数据库中:

//when we actually submit the form, we want to catch the action
    new Vue({
        el      : '#timeline',
        data    :   {
            post    : '',
        },
        http    :   {
            headers: {
                'X-CSRF-Token': $('meta[name=_token]').attr('content')
            }
        },
        methods : {
            postStatus : function (e) {
                e.preventDefault();
                console.log('Posted: '+this.post+ '. Token: '+this.token);
                $.ajax({
                    url         :   '/posts',
                    type        :   'post',
                    dataType    :   'json',
                    data        :   {
                        'body'  :   this.post,
                    }
                });
            }
        },
    });

However, this doesn't work so far, since there's this token mismatch exception. I don't know how to make it work. How to pass this token value to the controller. I have tried the following:

但是,到目前为止这还行不通,因为存在此令牌不匹配异常。我不知道如何让它工作。如何将此令牌值传递给控制器​​。我尝试了以下方法:

1) inside the form, I have added a vue name to the token:

1) 在表单中,我在令牌中添加了一个 vue 名称:

<input type="hidden" name="_token" value="YzXAnwB?C7qPK9kg7MGGIUzznEOCi2dTnG9h9?pB" v-model="token">

2) I have tried to pass this token value into the vue:

2)我试图将此令牌值传递给vue:

//when we actually submit the form, we want to catch the action
    new Vue({
        el      : '#timeline',
        data    :   {
            post    : '',
            token   : '',
        },
        methods : {
            postStatus : function (e) {
                e.preventDefault();
                console.log('Posted: '+this.post+ '. Token: '+this.token);
                $.ajax({
                    url         :   '/posts',
                    type        :   'post',
                    dataType    :   'json',
                    data        :   {
                        'body'  :   this.post,
                        '_token':   this.token,
                    }
                });
            }
        },
    });

... but in the console, vue doesn't even catch it :(

...但在控制台中,vue 甚至没有捕捉到它:(

This leads me to the following error:

这导致我出现以下错误:

TokenMismatchException in VerifyCsrfToken.php line 68:

VerifyCsrfToken.php 第 68 行中的 TokenMismatchException:

How do I fix it? Any ideas?

我如何解决它?有任何想法吗?

采纳答案by Pathros

I solved it thanks to these two answers:

由于这两个答案,我解决了它:

1) First I read this one, which led me to

1)首先我读了这个,这让我

2) This second one.

2)这第二个

So, in my form I keep this:

所以,在我的形式中,我保留了这个:

{{ csrf_field() }}

{{ csrf_field() }}

And inside the js file I only add the following (outside and above the Vue instance):

在 js 文件中,我只添加以下内容(在 Vue 实例的外部和上方):

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

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

So the whole js code is:

所以整个js代码是:

var csrf_token = $('meta[name="csrf-token"]').attr('content');
    /*Event handling within vue*/
    //when we actually submit the form, we want to catch the action
    new Vue({
        el      : '#timeline',
        data    :   {
            post    : '',
            token   : csrf_token,
        },
        methods : {
            postStatus : function (e) {
                e.preventDefault();
                console.log('Posted: '+this.post+ '. Token: '+this.token);
                $.ajax({
                    url         :   '/posts',
                    type        :   'post',
                    dataType    :   'json',
                    data        :   {
                        'body'  :   this.post,
                        '_token':   this.token,
                    }
                });
            }
        },
    });

回答by Md. Harun Or Rashid

Very Easy SolutionJust add a hidden fieldinside the form. An Example

Very Easy Solution只需在表单中添加一个隐藏字段即可。一个例子

<form id="logout-form" action="/logout" method="POST" style="display: none;">
    <input type="hidden" name="_token" :value="csrf">
</form>

Now add csrfvariable inside scriptat the vue file, like this. (Remember, it must be inside data).

现在在 vue 文件的脚本中添加csrf变量,就像这样。(请记住,它必须在data内部)。

<script>
     export default {
        data: () => ({
            csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
          }),        
    }
</script>

N.B.You will see a meta tag in your blade.phpfile like this.

注意您将在blade.php文件中看到这样的元标记。

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

If there is nothing like this, you need to place it there.

如果没有这样的东西,你需要把它放在那里。

回答by user247261

A better way is simply to pass the csrf token via a slot into the vue component.

更好的方法是简单地通过插槽将 csrf 令牌传递到 vue 组件中。

In blade.php file:

在blade.php 文件中:

@extends('layouts.app')

@section('content')
          <my-vue-component>
            {{ csrf_field() }}
          </my-vue-component>
@endsection

In MyVueComponent.vue

在 MyVueComponent.vue 中

   <form role="form">
       <slot>
         <!-- CSRF gets injected into this slot -->
       </slot> 
       <!-- form fields here -->
    </form>

回答by Marcus

My solution to this is that all vue components get csrf token right before a request is made. I put this in my bootstrap.js file.

我对此的解决方案是,所有 vue 组件都在发出请求之前获得 csrf 令牌。我把它放在我的 bootstrap.js 文件中。

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

Then have a class CoolApp.php

然后有一个类 CoolApp.php

    public function getScriptVariables()
    {
      return json_encode([
          'csrfToken' => csrf_token(),
      ]);
    }

回答by Jacopo Pace

Simply, I would suggest to put this in your PHP file:

简单地说,我建议把它放在你的 PHP 文件中:

<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).

通过这种方式,您可以轻松地从 JS 部分(在本例中为 Vue)导入您的 csrfToken。

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

此外,如果您将此代码插入到您的 PHP 布局文件中,您可以通过应用程序的任何组件使用该令牌,因为它window是一个 JS 全局变量。

Source: I got the trick from thispost.

来源:我从这篇文章中得到了诀窍。