LaravelAPI + Nuxt로 MultiAuth 구현

소개



현재 SIer5년째로 javascript(Jquery만), PHP(프레임워크 없음)를 2년 정도, C#(Windows 앱) 3년 정도 왔습니다.
여러가지 인연이 있어, 개인으로 최근 웹 서비스의 시작을 하게 되었습니다만 뭐 정말 웹 서비스를 시작하기 위한 지식이 거의 0과 같습니다

단지 향후의 경력을 생각했을 때 지금 그대로는 안 된다고 생각 챌린지하기로 했습니다.

우선은 최초로 기술을 습득하지 않으면 안되기 때문에, 배우는 & 아웃풋 하기 위해서 매회 투고해 가려고 생각합니다.
앞으로 자신에 대해 가려고 생각하는 것은 아래와 같은 기술입니다.
AWS
도커
CI/CD 환경 구축
라라벨
Nuxt.js
이번에는 Laravel + Nuxt에 대해 배웁니다.

전제



이미 필요한 마이그레이션 파일이 작성되었으며 나중에 구현할 만한 상태

백엔드


  • Laravel 5.8
  • jwt-auth

  • 프런트 엔드


  • nuxt 2.4
  • auth-module

  • 하고 싶은 일



    다음 세 가지 역할이 있다고 인증을 분리하고 싶습니다.
    각각 인증되어도 다른 역할의 기능을 사용할 수 없게 하고 싶다
    이번에는 API 측 인증을 구현합니다.
  • 구매자
  • 출점 사용자
  • 이벤트 관리자

  • 참고 사이트



    Multi-User API Authentication Using Laravel JWT

    Multi-user Authentication with Laravel and JWT

    구현 절차


  • config/auth.php에서 인증 설정하기
  • routes/api.php에서 인증이 필요한 API 정의
  • App/Exceptions/Handler.php에서 인증되지 않은 오류시 Json에서 반환하도록 구현
  • 각 모델 구현
  • 각 컨트롤러 구현

  • 인증 가드 설정


    config/auth.php
    역할별로 인증 가드 설정

    auth.php
    'guards' => [
            'web' => [
                'driver' => 'session',
                'provider' => 'users',
            ],
    
            'users' => [
                'driver' => 'jwt',
                'provider' => 'users',
            ],
    
            'shops' => [
                'driver' => 'jwt',
                'provider' => 'shops',
            ],
    
            'marche' => [
                'driver' => 'jwt',
                'provider' => 'marches',
            ],
        ],
    

    인증 시 연결되는 모델 정의

    auth.php
    'providers' => [
            'users' => [
                'driver' => 'eloquent',
                'model' => App\Models\User::class,
            ],
    
            'shops' => [
                'driver' => 'eloquent',
                'model' => App\Models\Shop::class,
            ],
    
            'marches' => [
                'driver' => 'eloquent',
                'model' => App\Models\Marche::class,
            ],
    
        ],
    

    비밀번호 알림에 사용할 테이블 설정

    auth.php
    'passwords' => [
            'users' => [
                'provider' => 'users',
                'table' => 'password_resets',
                'expire' => 60,
            ],
            'shops' => [
                'provider' => 'shops',
                'table' => 'password_resets',
                'expire' => 60,
            ],
            'marches' => [
                'provider' => 'marches',
                'table' => 'password_resets',
                'expire' => 60,
            ],
        ],
    

    인증이 필요한 API 정의


    routes/api.php인증이 필요한 API는 'middleware' => ['auth:XXXX']로 정의한다.

    api.php
    Route::group(['prefix' => 'user','middleware' => ['auth:users']], function (){
        Route::get('/me', 'Client\MeController@index');
    });
    
    Route::group(['prefix' => '/shop','middleware' => ['auth:shops']], function (){
        Route::get('/me', 'Shop\MeController@index');
    });
    
    Route::group(['prefix' => '/marche','middleware' => ['auth:marches']], function (){
        Route::get('/me', 'Marche\MeController@index');
    });
    

    인증되지 않은 오류시 Json에서 반환하도록 구현



    API가 인증 오류시 기본값이 아직 Json 형식으로 반환되지 않기 때문에
    인증 오류시 Json 형식으로 반환

    App/Exceptions/Handler.php
    protected function unauthenticated($request, AuthenticationException $exception)
    {
        return response()->json(['message' => $exception->getMessage()], 401);
    }
    

    참고 자료

    모델 구현



    사용자 모델을 대표 예로 이런 식으로 구현

    User.php
    <?php
    
    namespace App\Models;
    
    use Illuminate\Notifications\Notifiable;
    use Illuminate\Contracts\Auth\MustVerifyEmail;
    use Illuminate\Foundation\Auth\User as Authenticatable;
    use App\Notifications\Client\ResetPasswordNotification;
    use Tymon\JWTAuth\Contracts\JWTSubject;
    use App\Notifications\Client\VerifyEmail;
    
    class User extends Authenticatable implements JWTSubject, MustVerifyEmail
    {
        use Notifiable;
    
        /**
         * The attributes that are mass assignable.
         *
         * @var array
         */
        protected $fillable = [
            'name', 'name_phonetic', 'email', 'password', 'address', 'phone_number'
        ];
    
        /**
         * The attributes that should be hidden for arrays.
         *
         * @var array
         */
        protected $hidden = [
            'password', 'remember_token',
        ];
    
        /**
         * The attributes that should be cast to native types.
         *
         * @var array
         */
        protected $casts = [
            'email_verified_at' => 'datetime',
        ];
    
        public function getJWTIdentifier()
        {
            return $this->getKey();
        }
    
        public function getJWTCustomClaims()
        {
            return [];
        }
    
        public function sendPasswordResetNotification($token)
        {
            $this->notify(new ResetPasswordNotification($token));
        }
    
        public function sendEmailVerificationNotification()
        {
            $this->notify(new VerifyEmail);
        }
    }
    
    

    컨트롤러 구현



    컨트롤러의 인증 기능의 구현은 과거의 아래를 참조하면서 구현했다
    모던한 기술을 전혀 모르는 SIer5년째가 웹 서비스를 만들게 되었기 때문에 0부터 공부한다 ~Laravel jwt-auth편~

    주의점



    MultiAuth의 대응으로 가드명을 지정해 주지 않으면 인증이 잘 가지 않았다.
    만약 뭔가 좋은 방법이 있는 가르쳐 주시면 다행입니다. . .
    // authの部分をguard名を指定してあげる
    $this->auth->attempt($request->only('email', 'password'))
    ↓↓↓
    auth("users")->attempt($request->only('email', 'password'))
    

    좋은 웹페이지 즐겨찾기