Laravel CSRF 保护与 REST API

Posted

技术标签:

【中文标题】Laravel CSRF 保护与 REST API【英文标题】:Laravel CSRF protection with REST API 【发布时间】:2016-09-05 03:12:10 【问题描述】:

我的路由文件顶部有这段代码

Route::when('*', 'csrf', array('post', 'put', 'delete'));

当我测试我的 RESTful API 层时,我得到了令牌不匹配错误。如何解决这个问题?

我对用户可能执行的常规表单提交使用 CSRF 保护。但这对 API 有什么作用呢?我的 API 调用按以下常规路线分组

Route::group(array('prefix' => 'api'), function () 
Route::resource('shows', 'ShowsApiController');
Route::resource('episode', 'EpisodesApiController');
Route::resource('genre', 'GenresApiController');
);

【问题讨论】:

【参考方案1】:

在你的App\Http\Middleware\VerifyCsrfToken

你会有这样的课程,将你的路线添加到 $except

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier

  protected $except = [
    'shows/*',
    'episode/*',
    'genre/*',
  ];

【讨论】:

添加csrf异常是可以的,但这不是处理API的正确方式。为什么这不是做 API 的正确方法:cookie 将被添加到响应中——打破了无状态的概念; laravel 将尝试开始会话 - 失去一些昂贵的时间;在 web 组中添加新的中间件时,您将需要进行两倍的测试;如果您考虑节流,最终您将需要迁移到 API 中间件组。只是我的两分钱。 对我来说,您似乎有更好的解决方案,但有时人们并不关心“无国籍概念”或(在此处插入一个复杂的最佳实践术语),我并不是说它们不好或一些东西,但使用小应用程序并不需要让事情变得更复杂 我同意你关于小应用程序的看法,保持它们简单是至关重要的。但这里有另一个重要部分:如果你做的每一件事都尽可能简单,那么你就没有提高你的技能。作为一名程序员,我可以说,当我尝试改变某些东西时;做一些不同的事情,比以往任何时候,我学到了很多东西。干杯! 在 5.2 中添加但仍然 api 响应相同的错误TokenMismatchException in VerifyCsrfToken.php line 67:【参考方案2】:

您应该考虑为您的 web 和 api 层使用不同的中间件组。 Laravel 默认情况下,根据你使用的版本,使用web 中间件组。

如果您的 routes.php 文件中没有像 Route::group(['middleware' => 'web'], function () 这样的行,那么您的 laravel 版本就是默认使用它的版本。检查您的 RouteServiceProvider.php 文件中的这一行:https://github.com/laravel/laravel/blob/master/app/Providers/RouteServiceProvider.php#L56。

如果出现,请删除'middleware' => 'web' 部分并将自己的路由分组到routes.php。然后在你需要会话、csrf 和其他东西的部分使用web 中间件,并在不需要这些东西的地方使用api 中间件(api 中间件组不包括会话、加密的 cookie 和 csrf 验证)。

【讨论】:

是否有可能在特定控制器中禁用 如果您找到了解决方案,您能否关闭/回答问题 这个答案应该被选中!

以上是关于Laravel CSRF 保护与 REST API的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5:没有 CSRF 检查的 POST

Laravel CSRF 保护下的 JQuery AJAX 跨站请求

如何在Spring启动应用程序中进行REST调用而不在Spring安全性中禁用CSRF保护?

Laravel CSRF 保护

Django Rest Framework + AngularJS:CSRF 保护的正确方法?

在 laravel 中使用 REST API 的最佳身份验证方法是啥?