Laravel のPUSH 通知を独自の認証機構を持ったプライベートなチャンネルでやりとりするまでの実装手順をまとめました。
・独自の認証ルート定義
・独自の認証機構定義
・チャンネルのプライベート化(サーバー/クライアント両方)
が必要です。
※前提条件としてPUSH通知用のドライバとしてPusherを、PUSHサーバーとしてLaravel WebSockets を利用しています。
認証ルート定義
Laravel公式ドキュメント: Laravel 5.7 ブロードキャスト: 認証ルート定義
https://readouble.com/laravel/5.7/ja/broadcasting.html#defining-authorization-routes
上記のドキュメントに従い、PUSHクライアントを認証するためのルーティングを設定します。デフォルトですと
// app/Providers/BroadcastServiceProvider.php
class BroadcastServiceProvider extends ServiceProvider
{
...
public function boot()
{
Broadcast::routes();
...
}
}
として、Broadcast::routes で定義されています。ですが、LaravelEchoクライアントがPUSH通信の認可に使用するエンドポイントは独自に定義、設定できます。なので、認可のための独自のルーティングをルーティングファイルに設定し、さらに独自の認証機構も組み込みましょう。
※APIサーバーにて認可させるため、api.phpに追加し、さらに認証用の独自ミドルウェアを設定しています
// routes/api.php
// push/auth への POST を
// 独自の認証ミドルウェア push.auth で認証したうえで
// PushController の auth アクションで認可させる
Route::group(['middleware' => 'push.auth'], function () {
Route::group(['prefix' => 'push'], function () {
Route::post('auth', 'PushController@auth');
});
});
認証ミドルウェアの実装
こちらは通常のミドルウェア同様に Kernel.php のミドルウェアテーブルに追加したうえで、実装してください
// app/Http/Kernel.php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
...
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
...
'push.auth' => \App\Http\Middleware\PushAuthenticate::class,
...
];
...
}
// app/Http/Middleware/PushAuthenticate.php
<?php
namespace App\Http\Middleware;
class PushAuthenticate
{
...
public function handle($request, Closure $next)
{
$key = $request->input('key');
// do something authentication
...
return $next($request);
}
}
認可のエンドポイント実装
BroadcastingController の auth アクションと同様の実装を行います。Pusherの auth の結果をJSONで返すだけでよいです。
// app/Http/Controllers/PushController.php
class PushController extends BaseController
{
public function auth(Request $request, Broadcaster $broadcaster)
{
// pusher用の認証情報 $key, $secret, $appIdを取得する
...
// pusher の認証を行い、その結果を返す
$pusher = new Pusher($key, $secret, $appId);
$auth = $pusher->presence_auth(
$request->input('channel_name'),
$request->input('socket_id'),
'xxx');
$auth = json_decode($auth);
return response()->json($auth);
}
}
LaravelEcho 側に認可用エンドポイント設定
特に何もしなければLaraveEchoのクライアントは /broadcasting/auth エンドポイントで認証を行うため、authEndpoint オプションを設定、認証用のエンドポイントを変更します。Laravel 標準の auth を使わず独自認証を使うため、クライアントからの認証キーをURLに含めて送らせ認証させています
// resoutes/js/bootstrap.js
...
window.Echo = new Echo({
broadcaster: 'pusher',
// 認証情報としてクライアントからクエリストリングでキーを送る
// key はクライアント側に適宜定義する
authEndpoint: '/api/push/auth?key=' + key,
...
});
LaravelEchoクライアントからのlisten時にプライベートチャンネルを指定
Laravel公式ドキュメント: Laravel 5.7 ブロードキャスト: イベントのリッスン のプライベートチャンネルのイベントをリッスンしたい場合は~に従い下記のように書き換えます。
https://readouble.com/laravel/5.7/ja/broadcasting.html#listening-for-events
// 修正前
Echo.channel('channel').listen('Event', e => {...});
// 修正後
Echo.private('channel').listen('Event', e => {...});
Laravel の PUSH 機能を使ったシステム構築をお考えなら
宮城、仙台に限らず、PUSH機能を使ったシステム導入にお困りの方や、システムの構築可能なベンダーをお探しならば、ぜひ弊社までご相談ください。
宮城県仙台市のシステム開発会社FITS
https://www.fits-inc.jp/