🔑
Laravel8+Redis コマンドでワンタイムトークンの為の
前提
- ワンタイムトークンの前段であるトークンの操作処理を作り方を掲載
- php8
- redisの操作は
phpredis
- OSは
ubuntu20
- タイトルはトークンとしてあるが、以降はシグネチャー(signature) と表現する
- 掲載するコードは説明不要の最小限の内容且つ実用性のあるもの
特にワンタイムトークンとして利用しなければいけない訳ではなく、削除処理をロジックに組み込まなければ一定期間有効なトークンとして利用可能
作るコマンド
コマンド | 効用 |
---|---|
admin:signature:issue | 発行 |
admin:signature:validate | 有効性の検証 |
admin:signature:remove | 無効化 |
トークンを操作する処理の作成
bash
mkdir -p app/Repositories/Admin
touch app/Repositories/Admin/SignatureRepositoryInterface.php
touch app/Repositories/Admin/SignatureRepository.php
mkdir -p app/Services/Admin
touch app/Services/Admin/AccountServiceInterface.php
touch app/Services/Admin/AccountService.php
シグネチャの保存・取得・削除のみを提供する処理
app/Repositories/Admin/SignatureRepositoryInterface.php
<?php
declare(strict_types=1);
namespace App\Repositories\Admin;
use Illuminate\Support\Facades\Redis;
interface SignatureRepositoryInterface{
public function save(string $signature, int $lifetimeSeconds): bool;
public function get(string $signature): ?string;
public function delete(string $signature): void;
}
app/Repositories/Admin/SignatureRepository.php
<?php
declare(strict_types=1);
namespace App\Repositories\Admin;
use Illuminate\Support\Facades\Redis;
use Carbon\Carbon;
use App\Repositories\Admin\SignatureRepositoryInterface;
class SignatureRepository implements SignatureRepositoryInterface{
public function save(string $signature, $lifetimeSeconds): bool{
return Redis::set($signature
, Carbon::now()->addSeconds($lifetimeSeconds)->timestamp
, 'ex'
, $lifetimeSeconds
, 'nx');
}
public function get(string $signature): ?string{
return Redis::get($signature);
}
public function delete(string $signature): void{
Redis::command('del', [$signature]);
}
}
SignatureRepositoryをサービスコンテナにバインド
artisan
php artisan make:provider RepositoryServiceProvider
app/Providers/RepositoryServiceProvider.php
use App\Repositories\Admin\SignatureRepositoryInterface;
use App\Repositories\Admin\SignatureRepository;
public function register()
{
$this->app->bind(SignatureRepositoryInterface::class, SignatureRepository::class);
}
Signatureの発行・検証・無効化を提供する処理
app/Services/Admin/AccountServiceInterface.php
<?php
declare(strict_types=1);
namespace App\Services\Admin;
use Illuminate\Support\Facades\Redis;
interface AccountServiceInterface{
public function issueSignature(int $expired): ?string;
public function validateSignature(string $signature): bool;
public function revokeSignature(string $signature): void;
}
app/Services/Admin/AccountService.php
<?php
declare(strict_types=1);
namespace App\Services\Admin;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Str;
use App\Services\Admin\AccountServiceInterface;
use App\Repositories\Admin\SignatureRepositoryInterface;
class AccountService implements AccountServiceInterface{
private SignatureRepositoryInterface $signatureRepository;
public function __construct(SignatureRepositoryInterface $signatureRepository){
$this->signatureRepository = $signatureRepository;
}
public function issueSignature(int $expired): ?string{
$signature = Str::random(64);
return match($this->signatureRepository->save($signature, $expired)){
true => $signature
,false => null
};
}
public function validateSignature(string $signature): bool{
return match($this->signatureRepository->get($signature)){
null => false
,default => true
};
}
public function revokeSignature(string $signature): void{
$this->signatureRepository->delete($signature);
}
}
コマンドの作成
発行コマンド
artisan
php artisan make:command Admin/IssueSignatureCommand
app/Console/Commands/Admin/IssueSignatureCommand.php
<?php
namespace App\Console\Commands\Admin;
use Illuminate\Console\Command;
use App\Services\Admin\AccountService;
class IssueSignatureCommand extends Command{
protected $signature = 'admin:signature:issue
{expired=1800 : 有効期限(秒)指定}';
protected $description = 'ワンタイムキーを発行する';
public function __construct(){
parent::__construct();
}
public function handle(AccountService $accountService){
$expired = $this->argument('expired');
$result = $accountService->issueSignature($expired);
match($result){
null => $this->error('Issue failure. Please retry issue signature')
,default => (function($parent, $result) {
$parent->info('Signature issued!');
$parent->line($result);
})($this, $result)
};
}
}
発行コマンドの動作確認
- ヘルプの表示
artisan
php artisan admin:signature:issue -h
Description:
ワンタイムキーを発行する
Usage:
admin:signature:issue [<expired>]
Arguments:
expired 有効期限(秒)指定 [default: "1800"]
- 発行
artisan
php artisan admin:signature:issue 3000
Signature issued!
G2ZmtPVG0jNtACnwcGm36cf9egVEH4FYkUJ3sAPzULTWkPgrRZYU1SUB31LtXFi7
検証コマンド
artisan
php artisan make:command Admin/ValidateSignatureCommand
app/Console/Commands/Admin/ValidateSignatureCommand.php
<?php
namespace App\Console\Commands\Admin;
use Illuminate\Console\Command;
use App\Services\Admin\AccountService;
class ValidateSignatureCommand extends Command{
protected $signature = 'admin:signature:validate
{signature : 有効性の確認をするワンタイムキー}';
protected $description = 'ワンタイムキーの有効性を確認する';
public function __construct(){
parent::__construct();
}
public function handle(AccountService $accountService){
match($accountService->validateSignature($this->argument('signature'))){
true => $this->info('Signature is valid')
,default => $this->error('Signature is invalid')
};
}
}
検証コマンドの動作確認
- ヘルプ表示
artisan
php artisan admin:signature:validate -h
Description:
ワンタイムキーの有効性を確認する
Usage:
admin:signature:validate <signature>
Arguments:
signature 有効性の確認をするワンタイムキー
- 有効状態の検証
artisan
php artisan admin:signature:validate G2ZmtPVG0jNtACnwcGm36cf9egVEH4FYkUJ3sAPzULTWkPgrRZYU1SUB31LtXFi7
Signature is valid
無効化コマンド
artisan
php artisan make:command Admin/RevokeSignatureCommand
app/Console/Commands/Admin/RevokeSignatureCommand.php
<?php
namespace App\Console\Commands\Admin;
use Illuminate\Console\Command;
use App\Services\Admin\AccountService;
class RevokeSignatureCommand extends Command{
protected $signature = 'admin:signature:revoke
{signature : 無効化するワンタイムキー}';
protected $description = 'ワンタイムキーを無効化する';
public function __construct(){
parent::__construct();
}
public function handle(AccountService $accountService){
$this->line('Revoke signature: '.$this->argument('signature'));
$accountService->revokeSignature($this->argument('signature'));
$this->info('Signature revoked.');
}
}
-ヘルプの表示
artisan
php artisan admin:signature:revoke -h
Description:
ワンタイムキーを無効化する
Usage:
admin:signature:revoke <signature>
Arguments:
signature 無効化するワンタイムキー
- 無効化
artisan
php artisan admin:signature:revoke G2ZmtPVG0jNtACnwcGm36cf9egVEH4FYkUJ3sAPzULTWkPgrRZYU1SUB31LtXFi7
Revoke signature: G2ZmtPVG0jNtACnwcGm36cf9egVEH4FYkUJ3sAPzULTWkPgrRZYU1SUB31LtXFi7
Signature revoked.
無効状態のの検証
artisan
php artisan admin:signature:validate G2ZmtPVG0jNtACnwcGm36cf9egVEH4FYkUJ3sAPzULTWkPgrRZYU1SUB31LtXFi7
Signature is invalid
Discussion