본문 바로가기
Programming/Laravel(PHP)

[WSL] Laravel JWT 구현 (tymon/jwt-auth 패키지)

by 8ugust 2022. 1. 24.

JWT 구현 (tymon/jwt-auth 패키지)

 

 

1 )  tymon/jwt-auth 패키지 설치

$ composer require tymon/jwt-auth

 

 

2 ) Service Provider 및 Facade 추가

// config/app.php



// ...
'providers' => [
    // ...
    Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,
],


// ...
'aliases' => [
    // ...
    'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
    'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
];

 

 

3 ) 설정(Config) 파일 생성

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

 

 

4 ) JWT Secret Key 생성

// .env 파일에 JWT_SECRET 생성.

php artisan jwt:secret

 

 

5 ) JWT Middleware 생성 및 등록

php artisan make:middleware JwtMiddleware

 

// app\Http\Middleware\JwtMiddleware


namespace App\Http\Middleware;

use Closure;
use JWTAuth;
use Exception;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;

class JwtMiddleware extends BaseMiddleware {

	/**
	 * Handle an incoming request.
	 *
	 * @param  \Illuminate\Http\Request  $request
	 * @param  \Closure  $next
	 * @return mixed
	 */
	public function handle($request, Closure $next)
	{
        try {
            $user = JWTAuth::parseToken()->authenticate();
        } catch (Exception $e) {
            if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException) {
                return response()->json(['status' => 'Token is Invalid'], 403);
            } else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException) {
                return response()->json(['status' => 'Token is Expired'], 401);
            } else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenBlacklistedException) {
                return response()->json(['status' => 'Token is Blacklisted'], 400);
            } else {
                return response()->json(['status' => 'Authorization Token not found'], 404);
            }
        }
        return $next($request);
    }
}

 

// app/Http/Kernel.php


// ...
protected $routeMiddleware = [

	// ...
    'jwt.verify' => \App\Http\Middleware\JwtMiddleware::class,
];

 

 

6 ) Laravel Auth Guard 수정

// config/auth.php



// ...
'defaults' => [
    'guard' => 'api',
    'passwords' => 'users',
],

// ...
'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
        'hash' => false,
    ],
],

 

 

7 )  MySQL DataBase 생성

# root 계정 로그인
sudo su -
mysql -u root -p 


# 데이터베이스 생성
CREATE DATABASE your_database_name default CHARACTER SET UTF8;


# 권한 추가
GRANT ALL PRIVILEGES ON your_database_name.* TO your_user@localhost IDENTIFIED BY 'passowrd';


# 권한 확인
use mysql
select * from user where user = [your_user]

 

 

8 ) Database 연동 및 User 모델 생성

// .env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database
DB_USERNAME=your_username
DB_PASSWORD=your_password

 

// config/databse.php


// ...
'connection' => [

    // ...
    'mysql' => [
        'driver' => 'mysql',
        'url' => env('DATABASE_URL'),
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'your_database'),
        'username' => env('DB_USERNAME', 'your_username'),
        'password' => env('DB_PASSWORD', 'your_password'),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'prefix_indexes' => true,
        'strict' => true,
        'engine' => null,
        'options' => extension_loaded('pdo_mysql') ? array_filter([
            PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
        ]) : [],
    ]

]

 

// getJWTIdentifier()
// getJWTCustomClaims()
// 위 function을 제외한 나머지는 마음껏 커스텀 가능.


<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;


class User extends Authenticatable implements JWTSubject {
    use HasFactory, Notifiable;

    protected $connection = 'mysql';
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    /**
     * 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 [];
    }
}

 

 

9 ) Auth API 구현

// route/api.php


Route::group(['middleware' => 'api', 'prefix' => 'v1'], function () {
	
    // ...
    Route::post('auth/login', [AuthController::class, 'login']);
    Route::post('auth/logout', [AuthController::class, 'logout']);
    Route::post('auth/refresh', [AuthController::class, 'refresh']);
    Route::post('auth/me', [AuthController::class, 'me']);
    Route::post('auth/register', [AuthController::class, 'register']);

});

 

// app/Http/Controllers/AuthController.php


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Hash;
use App\Models\User;

class AuthController extends Controller {
    
    public function __construct() {
        $this->middleware('jwt.verify', ['except' => ['login', 'register']]);
    }

    // User Register
    public function register(Request $request) {
    	
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string',
        ]);
            
        if($validator->fails()){
            return response()->json([
                'status' => 'error',
                'success' => false,
                'error' =>
                $validator->errors()->toArray()
            ], 400);
        }
            
        $user = User::create([
            'name' => $request->input('name'),
            'email' => $request->input('email'),
            'password' => Hash::make($request->input('password')),
        ]);
            
        return response()->json([
            'message' => 'User created.',
            'user' => $user
        ]);	
    }

    // User Login
    public function login() {
        $credentials = request(['email', 'password']);

        if (! $token = auth()->attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }
        return $this->respondWithToken($token);
    }

    // User Auth
    public function me() {
        return response()->json(auth()->user());
    }

    // User Logout
    public function logout() {
        auth()->logout();
        return response()->json(['message' => 'Successfully logged out']);
    }

    // User Refresh
    public function refresh() {
        return $this->respondWithToken(auth()->refresh());
    }

    // Token
    protected function respondWithToken($token) {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth()->factory()->getTTL() * 60
        ]);
    }
	
	
}

 

 

10 ) Auth API 실행

10 - 1 ) User Register

 

10 - 2) User Login

 

 

10 - 3) User Authentication

 

 

 이제 UserLog 등 로그인 및 인증에 대한 커스텀을 추가하면 된다.

댓글