Laravel Sanctum
Laravel Sanctum을 사용하면 OAuth보다 훨씬 쉽게 API 인증을 구현할 수 있습니다.
Sanctum에서는 API 제공 방식을 세 가지로 나눕니다.
- API Token Authentication
- SPA Authentication
- Mobile Application Authentication
이 문서는 sanctum을 실무에 사용하면서 당시에 적용한 부분만을 기록하고 있습니다. 더 자세한 내용은 Laravel Sanctum 문서를 참고해주세요.
Sanctum을 설치
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
SPA에서 사용 (Vue)
.env
의 SANCTUM_STATEFUL_DOMAINS
에 도메인을 넣습니다.
SANCTUM_STATEFUL_DOMAINS=9cells.com
미들웨어를 추가합니다.
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
'api' => [
EnsureFrontendRequestsAreStateful::class, // 추가
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
API Controller에서 auth:sanctum
미들웨어를 사용합니다.
public function __construct()
{
$this->middleware('auth:sanctum');
}
Laravel 문서에서는 axios.get('/sanctum/csrf-cookie')
를 먼저 호출하고 API를 사용해야 한다고 말합니다.
하지만 저의 경우는 정확하게 SPA가 아니고 /login
웹 페이지가 별도로 제공되고 있어서, 로그인을 했을 경우 /sanctum/csrf-cookie
호출 없이 API 사용이 가능했습니다.
Mobile App에서 사용 (Flutter)
User 모델에 HasApiTokens trait를 추가합니다.
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
}
email, password, device_name을 넘기면 Sanctum token을 리턴하는 route를 만듭니다.
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
Route::post('/sanctum/token', function (Request $request) {
$request->validate([
'email' => 'required|email',
'password' => 'required',
'device_name' => 'required'
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
return $user->createToken($request->device_name)->plainTextToken;
});
여기서 반환되는 token을 API 요청 때 Authorization 헤더의 Bearer 토큰으로 사용합니다.
Flutter에서 API를 사용하는 예제.