【Laravel】Signed URLsを使って署名&有効期限付きのURLを生成する方法

Laravel
スポンサーリンク

はじめに

Laravelには「Signed URLs」と呼ばれる署名(期限)付きURLを生成する仕組みがあります。

この機能を使うと、例えば「一定期間のみ有効なダウンロードリンクを生成する」といったことができます。

この記事では「Signed URLs」の利用方法を紹介します。

Laravel - The PHP Framework For Web Artisans
Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing you to create without sweating the small...

署名(期限)付きURLの生成

ルーティングを設定

まずは今回使用するルーティングを”web.php”に追加します。

Route::get('/signed-url', 'SignedUrlController@index')->name('signed-url.index');

URLの生成

署名付きURLの生成には”URL::signedRoute” を使用します。

有効期限を設定したい場合は”URL::temporarySignedRoute”が用意されていますので、こちらを使うと良いでしょう。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use URL;

class SignedUrlController extends Controller
{
    public function index()
    {
        return view('signed-url.index', [
            'download_link' => URL::signedRoute('signed-url.download'),
            'temporary_download_link' => URL::temporarySignedRoute('signed-url.temporary-download', now()->addSeconds(30))
        ]);
    }
}
/resources/views/signed-url/index.blade.php

@extends('layouts.app')

@section('content')
    <div>
        <div>
            Signed URL
            {{ $download_link }}
        </div>
        <div>
            Temporary Signed URL
            {{ $temporary_download_link }}
        </div>
    </div>
@endsection

署名付きURLの取得

URL生成の準備ができたので、”/signed-url”にアクセスします。

そうすると下記のようなURLが表示されます。

{ドメイン}/signed-url/download?signature=b7cceee274377c2c8cac5f68f2de91a390d6c553b350a7b614bc2045b7d95765

{ドメイン}/signed-url/temporary-download?expires=1551517735&signature=3ad88c3284a196ce33296e9516a94ce18fd811c8014e9d41c6a1c9ee27988d09

署名付きURLのバリデーション

ルーティングの追加

web.php

Route::get('/signed-url', 'SignedUrlController@index')->name('signed-url.index');
Route::get('/signed-url/download', 'SignedUrlController@download')->name('signed-url.download');
Route::get('/signed-url/temporary-download', 'SignedUrlController@temporaryDownload')->name('signed-url.temporary-download');

RequestにhasValidSignatureを実行する

Signed URLのバリデーションには、リクエストに対して”hasValidSignature”を実行します。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use URL;

class SignedUrlController extends Controller
{
    public function index()
    {
        return view('signed-url.index', [
            'download_link' => URL::signedRoute('signed-url.download'),
            'temporary_download_link' => URL::temporarySignedRoute('signed-url.temporary-download', now()->addSeconds(30))
        ]);
    }

    public function download(Request $request)
    {
        if (!$request->hasValidSignature()) {
            abort(401);
        }

        return 'signed url ok';
    }

    public function temporaryDownload(Request $request)
    {
        if (!$request->hasValidSignature()) {
            abort(401);
        }
        return 'temporary signed url ok';
    }
}

ミドルウェアによるバリデーション

“/app/Http/Kernel.php”の”$routeMiddleware”に “\Illuminate\Routing\Middleware\ValidateSignature” を追加することで、ミドルウェアを利用したバリデーションが可能となります。

protected $routeMiddleware = [
    (中略)
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
];

web.phpでミドルウェアを使用する例を次に示します。

Route::get('/signed-url/download', 'SignedUrlController@download')->name('signed-url.download')->middleware('signed');
Route::get('/signed-url/temporary-download', 'SignedUrlController@temporaryDownload')->name('signed-url.temporary-download')->middleware('signed');

バリデーションに失敗した場合、アプリケーションは 403エラー を返却します。