Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
58
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@kumamon_engineer

Laravel5.6で署名付きURL(時間制限付き)の実装が簡単に出来るようになったので試した

Laravel5.6で署名付きURL(時間制限付き)の実装が簡単に出来るらしい

署名付きURLは実際のプロダクトで使用する機会も多いし、
時間制限付きの1時間以内にクリックしてくださいとかよくあるので、
簡単に実装できると凄くありがたいので試した。

公式の機能で追加になったらしいので、とりあえず確かめて見る。

以下のドキュメントを参考にした。
URL Generation

環境

  • PHP 7.1.16
  • Laravel Framework 5.6.15

実装

app/Http/Kernelに以下を記載する。

app/Http/Kernel.php
protected $routeMiddleware = [

    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,

];

あとは例に合わせてURLを作って、viewでリンクを作ってみる。

SignedRoute(...)・・・署名付きURL生成
temporarySignedRoute(...)・・・署名付きURL生成(時間制限付き)

今回は時間制限付きを試したいのでtemporarySignedRouteを使う。

  • 実際に実装で使いそうなuseridを指定している。(とりあえず固定で1)
  • 第2引数に有効時間を設定。下記の例は5秒以内にクリックしないとエラーになる。(now()->addSeconds(5))
routes/web.php
use Illuminate\Support\Facades\URL;
use Illuminate\Http\Request;

Route::get('/', function () {
    // URL生成
    $url = URL::temporarySignedRoute('unsubscribe', 
                                      now()->addSeconds(5), 
                                      ['user' => 1]);

    // とりあえずwelcomページにリンクを出して見る
    return view('welcome')->with('url',$url);
});

そして上の設定のルート先の内容が以下。
5秒以内にリンクをクリックすると、view('safe')のページが出る。
5秒以降のエラー遷移は->middleware('signed');がやってくれる。

routes/web.php
Route::get('/unsubscribe/{user}', function (Request $request) {

    return view('safe');

})->name('unsubscribe')->middleware('signed');

エラー遷移は->middleware('signed');がやってくれる。と書いたが、
このミドルウェアは自動的に403エラーレスポンスを返すと書いてあるので
resources/views/errors/403.blade.phpを用意した。

動作確認

まず、ルート画面に生成したURLを埋め込むと、以下のようなリンクが出た。

http://.../unsubscribe/1?expires=1523128426&signature=63b4744eb3aea943ddd7411d92bf2d8cea528dda011e29a9da128fac5c7e8ab7
  • 5秒以内にクリック
    view('safe')の画面が表示された。

  • 5秒以降にクリック
    403エラーの画面が表示された

validation

また実際に使いそうな処理としてvalidation判定して処理を分ける場合は、
$request->hasValidSignature()を使うため、->middleware('signed');を外した。
今度は401エラーを使いたいのでresources/views/errors/401.blade.phpを用意して確認した。

routes/web.php
Route::get('/unsubscribe/{user}', function (Request $request) {
    if (! $request->hasValidSignature()) {
        abort(401);
    }
    return view('safe');

})->name('unsubscribe');
  • 5秒以内にクリック
    view('safe')の画面が表示された。

  • 5秒以降にクリック
    401エラーの画面が表示された

結果

本当に簡単に実装できた。時間制限設定も簡単。
今後、Laravel5.6以上で1時間以内にクリックとかでURLメール送る機能とかを作る時が来たら使って見る。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
58
Help us understand the problem. What are the problem?