

APIを叩くほう・受け取る方ともにフレームワークはLaravelで、guzzleで外部APIを叩いています。

その際に、送った先のプロジェクトがtokenCheckはオンにしているため、tokenMissMatchExceptionエラーが出ます。(VerifyCsrfTokenミドルウェアによるチェックのため)

下記プログラムのheadersの部分にtokenを入れて飛ばしていますが、エラーは変わりません。

guzzleで外部APIを叩いた際に、tokenチェックを通るようにするためにはどうすればいいでしょうか？

[code]

    $client = new Client();
    // ***送信先***URL
    $url = 'https://dev.management.herokuapp.com/hoge/hoge_insert;
    // 送信処理
    $res = $client->request('post', $url,
            ['headers' => [
                'Content-type' => 'Application/json',
                'Authentication' => csrf_token(),
            ],
            'timeout' => 15000,
            'cache' => false,
            'dataType' => 'json',
                 'data' => [
                     'userId' => 1
                 ]
            ]);
        $data = json_decode($res->getBody(), true);
        $response = JsonResponse::create($data, 200);
        $response->send();
    
[/code]


CC BY-SA 3.0
2016-10-26T06:59:18.237
29910
2016-10-26T11:47:27.357
14661
question
javascript api cron
クロスドメインの外部APIでtokenMissmatchExceptionエラー


LaravelのVerifyCsrfTokenクラスの実装を見ると、  
tokenをヘッダに設定する場合の名称が「X-CSRF-TOKEN」となっています。  
拡張等をしている場合は、何をどう受け取っているか分からないので、  
外部APIを解析するか、問い合わせるしかないと思います。

[code]

    protected function tokensMatch($request)
    {
        $sessionToken = $request->session()->token();
        $token = $request->input('_token') ?: $request->header('X-CSRF-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);
    }
    
[/code]

下記を修正してみてください。

[code]

    'Authentication' => csrf_token(),
    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    'X-CSRF-TOKEN' => csrf_token(),
    
[/code]


CC BY-SA 3.0
2016-10-26T07:12:42.040
29911
2016-10-26T08:11:21.130
2016-10-26T08:11:21.130
19001
19001
29910
answer


CSRFトークンを送信するヘッダ名が間違っているのもそうですが、別プロジェクトのAPIを呼び出すのであれば、呼び出し側の `csrf_token()`
はAPI側の `csrf_token()` の値とは異なり、やはりエラーになるのではないでしょうか。

というか・・・CSRF攻撃への対策は不要なのではありませんか？

第三者があらかじめ仕込んでおいたリクエストをログイン済みのセッションで送信させるだけで、そのユーザーとして操作を実行できてしまうのがCSRF攻撃です。ログインを伴わない、あるいは攻撃者が自分でログインできるなら、こんな手を使わずとも自分で攻撃すればよく、この対策は無意味です。また「あらかじめ仕込んでおいたリクエストをログイン済みのセッションで送信させる」ことができない場合も、攻撃できないのですから対策する意味がありません。

正規のAPI呼び出しであることを検証する必要があるなら、IPアドレスで制限したり、リクエストに[メッセージ認証コード（MAC）](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E8%AA%8D%E8%A8%BC%E7%AC%A6%E5%8F%B7)を付けたり、別の方法を取った方がいいように思います。


CC BY-SA 3.0
2016-10-26T11:47:27.357
29918
2016-10-26T11:47:27.357
8000
29910
answer