quynhnguyenthe / laraliff
LIFF authentication for Laravel
v1.0.0
2023-12-25 10:35 UTC
Requires
- php: >=7.0.0
- guzzlehttp/guzzle: ^5|^6|^7
- illuminate/support: ^5.5|^6|^7|^8
- tymon/jwt-auth: ^1.0
README
Overview
- LIFFアプリ Document LIFF
- tymondesigns/jwt-auth Repo jwt
What you can do with laraliff
- LIFF's [ID token] (https://developers.line.biz/ja/docs/liff/using-user-profile/#%E3%83%A6%E3%83%BC%E3%82%B5%E3%82%99%E3%83%BC%E6%83%85%E5%A0%B1%E3%82%92%E3%82%B5%E3%83%BC%E3%83%8F%E3%82%99%E3%83%BC%E3%81%A6%E3%82%99%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B)Using user data in LIFF apps and servers
- Once authenticated, the transition is to authenticate using JWT.
How to use
composer require quynhnguyenthe/laraliff
tymondesigns/jwt-auth Create jwt config file
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
Create laraliff config file
php artisan vendor:publish --provider="QuynhNguyenThe\Laraliff\Providers\LaraliffServiceProvider"
JWT secret key generate
php artisan jwt:secret
ADD LIFF_CHANNEL_ID to .env
...
LIFF_CHANNEL_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Add the following to the schema of the table used for authentication
liff_id
- LIFF ID
name
- Name in line app
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('liff_id')->unique(); $table->string('name'); $table->timestamps(); }); } ... }
※Schema name can be changed from config
<?php return [ 'liff_channel_id' => env('LIFF_CHANNEL_ID', 'liff_channel_id'), 'fields' => [ 'liff_id' => 'liff_id', 'name' => 'name', ], ];
Add the following method to the model used for authentication
namespace App; use Tymon\JWTAuth\Contracts\JWTSubject; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable implements JWTSubject { use Notifiable; // Rest omitted for brevity /** * Get the identifier that will be stored in the subject claim of the JWT. * * @return mixed */ public function getJWTIdentifier() { return $this->getKey(); } /** * Return a key value array, containing any custom claims to be added to the JWT. * * @return array */ public function getJWTCustomClaims() { return []; } }
Change config/auth.php
'defaults' => [ 'guard' => 'api', 'passwords' => 'users', ], ... 'guards' => [ 'api' => [ 'driver' => 'laraliff', 'provider' => 'users', ], ],
Add route for authentication
Route::group([ 'middleware' => 'api', 'prefix' => 'auth' ], function ($router) { Route::post('login', 'AuthController@login'); Route::post('logout', 'AuthController@logout'); Route::post('refresh', 'AuthController@refresh'); Route::post('me', 'AuthController@me'); });
Create a controller for authentication
<?php namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use App\User; use QuynhNguyenThe\Laraliff\Services\Exceptions\LiffUnverfiedException; use QuynhNguyenThe\Laraliff\Services\LiffVerificationService; class AuthController extends Controller { public function __construct() { $this->middleware('auth:api', ['except' => ['login']]); } public function register(LiffVerificationService $verificationService) { try { $liff = $verificationService->verify(request('token')); } catch (LiffUnverfiedException $e) { return response()->json(['error' => 'LIFF ID Token is unauthorized'], 401); } $user = User::create([ 'liff_id' => $liff['sub'], 'name' => $liff['name'], 'picture' => $liff['picture'], ]); return response()->json(auth('api')->login($user)); } public function login() { try { $jwt = auth('api')->attempt(request(['liff_id_token'])); } catch (LiffUnverfiedException $e) { return response()->json(['error' => 'LIFF ID Token is unauthorized'], 401); } if (!$jwt) { return response()->json(['error' => 'User not found'], 404); } return response()->json($jwt); } public function me() { return response()->json(auth('api')->user()); } public function logout() { auth()->logout(); return response()->json(['message' => 'Successfully logged out']); } }