Vue Router Laravel 5.3 Vue 2 JS 上的 CSRF 令牌复制

Posted

技术标签:

【中文标题】Vue Router Laravel 5.3 Vue 2 JS 上的 CSRF 令牌复制【英文标题】:CSRF Token Duplication on Vue Router Laravel 5.3 Vue 2 JS 【发布时间】:2017-03-30 19:42:49 【问题描述】:

所以我的问题是生成了会话令牌。

以及我通过 AJAX 或 AXios 发送的令牌(因为我使用 vue 和 vue 路由器获取 API)

不匹配

这是我发布数据时得到的回复

ajax令牌等于主刀片模板的meta标签中的令牌

使用这个标签

app.blade.php 中的元标记

<meta name="csrf-token" content=" csrf_token() ">
<script>
    window.Laravel = <?php echo json_encode([
        'csrfToken' => csrf_token(),
    ]); ?>
</script>

Axios 的拦截器(目的是从 meta Tag 中注入 csrf_token)

Vue.axios.interceptors.request.use(function (config) 

    config.headers['X-CSRF-TOKEN'] = Laravel.csrfToken;
    console.log(config);
    return config;
  , function (error) 
    // Do something with request error
    return Promise.reject(error);
);

回复:

array:1 [
  "SessionToken" => "JfhmtCaTiQ49BtF2VK3TysvYnEQSE9n5i1uiHegO"
]
array:1 [
  "AjaxToken" => "WqKOiaunbvJbxIsnEjetFoCm1mvdUYESRqfXO2lv"
]

验证CSRFToken中间件方法:

  protected function tokensMatch($request)
    
        $sessionToken = $request->session()->token();

        $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');

        dd(['SessionToken' => $sessionToken],['AjaxToken' => $token]);
        if (! $token && $header = $request->header('X-XSRF-TOKEN')) 
            $token = $this->encrypter->decrypt($header);
        

        if (! is_string($sessionToken) || ! is_string($token)) 
            return false;
        

        return hash_equals($sessionToken, $token);
    

所以我想出了这个想法,但它不起作用,因为我从 api 获得的令牌是 null 或空

这是我的 RegisterComponent.vue 中的方法

    submitForm() 
        this.axios.get('/token')
            .then(response => 
               this._token = response.data
                   this.axios.post('/register',this.data)
                        .then(responseNew => 
                            console.log(responseNew.data);
                        )
                        .catch(responseNew => 
                            this.errors = responseNew.data;
                        )
            );
    

如您所见,我从路由文件夹中的 api.php 获取令牌

我也使用 Laravel 的认证 api 并将其放在 api 路由上

这里是 api.php

Route::group(['middleware' => 'web'], function() 
    Auth::routes();
);

Route::get('/token',function() 
   dd(csrf_field());
);
Route::get('/user', function (Request $request) 
    return $request->user();
)->middleware('auth:api');

Route::resource('/users','UserController');

Route::group(['middleware' => 'auth'], function () 


Route::resource('/stores','StoreController');

Route::resource('/items','ItemController');

Route::resource('/transactions','StoreController');

Route::resource('/managers','ManagerController');

Route::resource('/employees','EmployeeController');

Route::resource('/customers','CustomerController');

Route::resource('/tags','TagController');

);

那么我怎样才能防止它生成会导致不匹配的令牌呢?

任何回答这个问题的人肯定会帮助我的 SPA(单页应用程序)的身份验证

它也给了我响应状态 302

【问题讨论】:

有人想帮忙吗? 【参考方案1】:

你好像有点误会了。您已经为 axios 配置了 csrf 令牌,因此每个请求都会有一个包含令牌的标头字段,然后您只需要确保每个请求在到达您的业务逻辑之前都经过 laravel 的 csrf 令牌验证功能,这就是您需要做的一切防止csrf。 post('/register') 之前的 get('/token') 似乎没有必要。

另外,谈到/token 路由本身,csrf_field 在这里并不合适,因为它会生成一个隐藏的表单字段(除了我们之前讨论过的另一种发送 csrf 令牌的方式)嵌入到 @ 987654325@ file like &lt;form&gt;...&lt;?=csrf_field()?&gt;...&lt;/form&gt; => &lt;form&gt;...&lt;input type="hidden" name="laravel_csrf_token" value="***"&gt;...&lt;/form&gt;,这使得通过xhr请求csrf_field的结果毫无意义。

【讨论】:

以上是关于Vue Router Laravel 5.3 Vue 2 JS 上的 CSRF 令牌复制的主要内容,如果未能解决你的问题,请参考以下文章

VueJS 2 vue-router 2 (laravel 5.3)

Vue Router Laravel 5.3 Vue 2 JS 上的 CSRF 令牌复制

如何在 Laravel 5.3 中使用带有 Vue.js 2.0 的组件中使用外部 html 模板

VueRouter 未定义

带有 Laravel 5.3 的 Vue 多选

Laravel 5.3 vue 2组件不渲染