我在写一个 ajax post 控制器的时候想到了需要做 csrf 防御。看网上说 ajax 发请求的时候可以加_token 字段或者设置请求头来解决身份问题。我在 Illuminate\Foundation\Http\Middleware\VerifyCsrfToken 中也看到了相关的代码:
protected function tokensMatch($request)
{
$sessionToken = $request->session()->token();
//使用_token 字段或者请求头中的 X-CSRF-TOKEN 做$token
$token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');
if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
//没有的话使用 cookie 中加密的 X-XSRF-TOKEN 解密之后作为$token
$token = $this->encrypter->decrypt($header);
}
if (! is_string($sessionToken) || ! is_string($token)) {
return false;
}
//判断是否相等
return hash_equals($sessionToken, $token);
}
好了,下面说我的疑问,
Route::group([
'prefix' => 'api'
], function(){
Route::post('/collection/collect', 'Collection\Rest\CollectionCollectController@post')
->name('collectionCollect');});
以上是路由,以下是控制器
<?php
namespace App\Http\Controllers\Mass\Collection\Rest;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class CollectionCollectController extends Controller
{
public function post(Request $request)
{
DB::table('collection_product')->insert([
'c_eid' => $request->get('c_eid'),
'p_eid' => $request->get('p_eid')
]);
return [
'status' => 'ok'
];
}
}
我在使用使用 js 异步访问该路由的时候在上面说到的tokensMatch
方法中试图打印出$token
但是发现程序并没有走这个中间件。
protected function tokensMatch($request)
{
$sessionToken = $request->session()->token();
//使用_token 字段或者请求头中的 X-CSRF-TOKEN 做$token
$token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');
if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
//没有的话使用 cookie 中加密的 X-XSRF-TOKEN 解密之后作为$token
$token = $this->encrypter->decrypt($header);
}
if (! is_string($sessionToken) || ! is_string($token)) {
return false;
}
//打印$token,但是发现这里没有执行
dd($token);
return hash_equals($sessionToken, $token);
}
这样看来,是需要自己将 VerifyCsrfToken 中间件加到 Kernel.php 中的$middlewareGroups
中吗?
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
加入到'api'
中?
1
jellybool 2017-03-21 16:31:43 +08:00 via iPhone
看你路由注册在 web.php 还是 api.php
|
2
zaishanfeng 2017-03-21 16:34:42 +08:00 via Android
取消就行。 往这各类上面看 有个变量是控制哪些路由可以取消
|
3
xx19941215 OP @jellybool 注册在 api 里面
|
4
xx19941215 OP 结帖,是需要的。
|