使用REST API的Laravel CSRF保护

12

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

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');
});
2个回答

10

在您的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中间件组。只是我的个人意见。 - Giedrius Kiršys
2
在我看来,你似乎有一个更好的解决方案,但有时人们并不在意"无状态概念"或(在此插入一个复杂的最佳实践术语), 我不是说他们不好或什么,但小应用程序不需要让事情变得更加复杂。 - Achraf Khouadja
1
我同意您关于小应用程序的看法,保持简单至关重要。但这里还有另一个重要的部分:如果您尽可能地简化一切,那么您就无法提高自己的技能。作为一名程序员,我可以说,当我尝试改变某些东西;做一些与以往不同的事情时,我会学到很多东西。干杯! - Giedrius Kiršys
在5.2版本中新增了,但API响应仍然出现相同的错误VerifyCsrfToken.php line 67: TokenMismatchException - 151291

9
您应该考虑为您的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验证)。

有没有可能在特定的控制器中禁用? - Vijayanand Premnath
如果你已经找到了解决方案,你能否关闭/回答这个问题? - Achraf Khouadja
这个答案应该被选中! - Ahsaan Yousuf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接