Laravel JWT – 4. 토큰 갱신하기 > IT 기술백서

미들웨어에서 토큰이 만료되었으면 갱신한뒤 response 헤더에 갱신된 토큰을 보내준다.

프론트에서는 response.data 에 refreshed_token이 있을경우 기존토큰을 버리고 이 토큰을 저장하고 사용한다.

 

[code]

<?php

namespace App\Http\Middleware;

use Illuminate\Auth\Middleware\Authenticate as Middleware;

use Tymon\JWTAuth\Exceptions\TokenExpiredException;

use Tymon\JWTAuth\Exceptions\TokenInvalidException;

use Tymon\JWTAuth\Exceptions\JWTException;

use Closure;

use Auth;

use JWTAuth;

class Authenticate extends Middleware

{

 

 

    public function handle($request, Closure $next, …$guards)

    {

        if ($request->is(‘api/*’)) {

            try {

                JWTAuth::parseToken()->authenticate();

            } catch (\Exception $e) {

                // 잘못된 토큰일때

                if ($e instanceof TokenInvalidException) {

                    $status = 401;

                    $message = ‘This token is invalid. Try login’;

                    return response()->json(compact(‘status’, ‘message’), 401);

                // 토큰이 만료되었을 때

                } elseif ($e instanceof TokenExpiredException) {

                    try {

                        // 토큰 갱신

                        $refreshed_token = Auth::guard(‘api’)->refresh();

                        JWTAuth::setToken($refreshed_token)->toUser();

                        $response = $next($request);

                        $content = json_decode($response->content(), true);

 

                        // response.data 에 refresh 된 토큰을 추가해 준다

                        if (json_last_error() === JSON_ERROR_NONE) {

                            $content[‘refreshed_token’] = $refreshed_token;

                            $content = json_encode($content);

                            $response->setContent($content);

                        }

                        return $response;

                    } catch (JWTException $e) {

                        return response()->json([

                            ‘code’ => 103,

                            ‘message’ => ‘Token cannot be refreshed, Try login again’

                        ], 401);

                    }

                } else {

                    $message = ‘Authorization Token not found’;

                    return response()->json(compact(‘message’), 404);

                }

            }

            return $next($request);

        } else {

            $this->authenticate($request, $guards);

            return $next($request);

        }

    }

 

    /**

     * Get the path the user should be redirected to when they are not authenticated.

     *

     * @param  \Illuminate\Http\Request  $request

     * @return string|null

     */

 

 

    protected function redirectTo($request)

    {

        if ($request->expectsJson() || $request->is(‘api/*’)) {

            return route(‘api.unauthorized’);

        }

        return route(‘login’);

    }}

[/code]

 

nuxt 에서의 처리

/plugins/axios.js

[code]

export default function ({ $axios, store }) {

  // 응답 status 가 200 대가 아니면 에러처리

  $axios.defaults.validateStatus = (status) => {

    return status >= 200 && status < 300

  }

  // 요청시 header 에 토큰 실어보냄

  $axios.onRequest((config) => {

    config.headers.common.Authorization = `Bearer ${store.state.auth.access_token}`

  })

  // 토큰 refresh 되었을때 처리

  $axios.interceptors.response.use(

    (response) => {

      const data = response.data

      if (data.refreshed_token) {

        store.commit(‘auth/SET_TOKEN’, data.refreshed_token)

      }

      return response

    },

    (error) => {

      return Promise.reject(error)

    }

  )

}

[/code]

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤