9Cells

Laravel Sanctum

Laravel Sanctum을 사용하면 OAuth보다 훨씬 쉽게 API 인증을 구현할 수 있습니다.

Sanctum에서는 API 제공 방식을 세 가지로 나눕니다.

이 문서는 sanctum을 실무에 사용하면서 당시에 적용한 부분만을 기록하고 있습니다. 더 자세한 내용은 Laravel Sanctum 문서를 참고해주세요.

Sanctum을 설치

composer require laravel/sanctum

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"

php artisan migrate

SPA에서 사용 (Vue)

.envSANCTUM_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를 사용하는 예제.