🦀

laravel5.8¦表示時間制限付きURLページへ遷移するQRコードをつくる

2020/09/25に公開

概要

題名がわかりづらい…
QR画像を読み取る → 指定した時間内であれば設定したURLページに飛ぶAPI を実装してみた。

環境

・laravel 5.8
・php 7.2

実装

Simple QrCodeを使う

Simple QrCodeを使いました。
最終的にPNGにしたかったのですが、画像処理を行うライブラリが入ってなくてエラーに…
もしエラーになる場合はphpinfo() でgdセクションを確認するか、

$ php -m

で出てくるか確認して、もしphp-gdがない場合はインストールしましょう💫

dockerの起動時にエラーが出た場合

docker環境で実装しており、dockerの起動時にエラーがでて途方にくれていたのですが
PHP GD をインストールするための Dockerfile の少し複雑な内容メモ
と、記事に記載されていた
library/php – Docker Hub を参考に修正したところエラーがでなくなりました。ありがとうございました…!

UUIDを生成する

[php/Laravel]UUID生成の記事を参考に...むしろほぼそのまま...実装しました。本当にありがとうございました…!

class Uuid
{
    protected $uuid;
    public function __construct($prefix = '', $entropy = false, $hash = null)
    {
        switch ($hash) {
            case 'md5':
                $this->uuid = md5(uniqid($prefix, $entropy));
                break;
            default:
                $this->uuid = uniqid($prefix, $entropy);
            break;
        }
    }
    public function __toString()
    {
        return $this->uuid;
    }
}

コントローラーの作成

30分のところは一応ベタ書きせずconfig/constという定数ファイルを作成してそこから取得するようにしました。

use Illuminate\Http\Request;
use Illuminate\Support\Facades\URL;
use Uuid;
use Carbon\Carbon;
use App\Http\Requests\CheckinRequest;
use SimpleSoftwareIO\QrCode\Facades\QrCode;

class CheckinController extends Controller
{
    public function create(CheckinRequest $checkinRequest)
    {
        $token = new Uuid('', true,'md5');
        // urlの有効期限を30分にする
        $time  = Carbon::now()->addMinutes(config('const.ThirtyMinutes'));
       // フォーマットを指定してbase64化する
        $src = base64_encode(QrCode::format('png')->size(200)->generate(URL::temporarySignedRoute('checkin', $time, ['qr_token' => $token])));

        return view('/checkin',compact('src'));
    }
}

web.phpにルートの作成

Route::get('/checkin/{qr_token}', function (Request $request) {
    if (!$request->hasValidSignature()) {
        abort(500);
    }
    echo 'Created_page';
})->name('checkin');

有効期限切れの場合に403ではなく500にしたかったのでミドルウェア登録せずコメントアウトにしました。

// ‘signed’ => \Illuminate\Routing\Middleware\ValidateSignature::class

bladeファイルの作成

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
</head>
<body>
    <div class="flex-center position-ref full-height">
        <div class="content">
            <div class="title">
            作成したQRコード</br>
            <img src="data:image/png;base64,{{ $src }}"></br>
            </div>
        </div>
    </div>
</body>
</html>

これでQR画像が表示されました('ᴗ' )

postmanで確認していたので、あの画面にQR画像がでた時はちょっとテンション上がりました(* 'ᵕ' )!
URLの有効期限を30分にしているので、30分以内であればechoしたCreated_pageが表示され、30分以降であれば500ページに推移します。

実際はAPIでbase64化した時間制限つきURLのQRコードをjsonで送って欲しいとのことだったので、コントローラーの最後はjsonにしました。

return response()->json(['qrcode' => $src])->setStatusCode(201);

手間どったけど実装できると感慨深い...

Discussion