Laravel8 Requestクラスでバリデーション(ヘッダー編)

laravel

記事について

ヘッダーに含まれる値をlaravel8のRequestクラスでバリデーションするメモ。あくまでサンプルで通しで動作確認はしていないので、エラーが出たらごめんなさい。

ヘッダーチェックを入れるような場合は主にAPIリクエストだと思うので、そういう時に使うかもしれないやつ。

リクエスト内容

以下のようなリクエストヘッダーを送るとする。今回取得したいのは一番下の「api-token」の値。

:authority: www.ukkari-san.net
:method: GET
:path: /
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: ja,en-US;q=0.9,en;q=0.8
cookie: _ga=GA1.2.1520150017.1664441984; __gads=ID=3a890cbb11811866-22461884bfd60017:T=1664441984:RT=1664441984:S=ALNI_MaZxxBsATW1_WHjlsXy0pGjGXsAyA; wordpress_test_cookie=WP%20Cookie%20check; wp-settings-1=libraryContent%3Dbrowse%26posts_list_mode%3Dlist; wp-settings-time-1=1664442054; wp_lang=ja; wordpress_logged_in_a36a798e68a8ec3b58a2b05bfda40516=fortune%7C1666874013%7CwjHwzPte8rISl1ud2qb02jJeoVhBut5iZVgaeyhKCrl%7C6f7c5cdade10e6342d696bcd36ef6b52ff3b94c2e8f0e5cac68653796988ca5f; __gpi=UID=000009febb5927e6:T=1664441984:RT=1665664572:S=ALNI_MZDF1n2XoF1WWSSgO4YlutRdsm9gA
sec-ch-ua: "Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: none
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
api-token: abcdefg123456

これはリクエストを送る側のlaravelの例。Clientを生成して、ヘッダーを追加、リクエストを送信している。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class SampleApiController extends Controller
{

    public function index(Request $request) {
        $client = new \GuzzleHttp\Client();
        $response = $client->request('GET', 'https://www.ukkari-san.net/api/v2/hoge?foo=bar', [
            'headers' => [
                'api-token', 'abcdefg123456'
            ]
        ]);
	      // 今のリクエストに追加するような場合はこっち
	      //$request->headers->set('api-token', 'abcdefg123456');
        ...

Requestクラスの内容

こちらが本題で、受け取る側でバリデーションを行う場合の記述。

ヘッダーの値をprepareForValidation()で一度取り込んでから、いつも通りのrule()内でバリデーションする形。apiで使うような場合の記述なので、通常のフォーム等で使いたい場合、failedValidation()のメソッドをまるごと消せばOK。

<?php

namespace App\Http\Requests\Api;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;

class HeaderCheckRequest extends FormRequest
{
    #protected $stopOnFirstFailure = true;

    public function authorize()
    {
        return true;
    }

    protected function prepareForValidation()
    {
        $this->merge(['api-token' => $this->headers->get('api-token')]);
    }

    public function rules()
    {
        $rules = [];
        $rules['api-token'] = [
            'auth' => function ($attribute, $value, $fail) {
                if (config("hoge_fuga_key") != $value) {
                    $fail('認証情報が正しくありません。');
                }
            },
        ];
        return $rules;
    }

    public function messages()
    {
        return [
        ];
    }

    public function attributes()
    {
        return [
        ];
    }

    public function failedValidation(Validator $validator)
    {
        $res = response()->json([
            'result' => [],
            'message' => $validator->errors(),
        ], 400);
        throw new HttpResponseException($res);
    }
}

余談

apiの呼び出しもたまに使う割によく忘れている気がしますw

コメント

タイトルとURLをコピーしました