minstudio

JWT(JSON Web Token)를 이용한 사용자 인증

과거에는 '세션'을 이용해 로그인을 유지했지만, 최신 API 서버들은 주로 JWT(JSON Web Token)를 사용합니다. JWT는 사용자 정보와 서명이 들어있는 '전자 VIP 출입증'으로, 서버가 상태를 기억할 필요 없이(Stateless) 빠르고 안전하게 인증을 처리합니다.

👨‍🚀
클라이언트
Authorization:
Bearer eyJhb...
➡️
🕵️‍♂️
JWT 미들웨어

"출입증(토큰) 위조 여부 검사"

➡️
💎
비밀 데이터

접근 승인!

bash
// composer require firebase/php-jwt
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$secretKey = 'super_secret_key_123'; // 절대 노출되면 안됨 (.env 사용)

// 1. 토큰 발급하기 (로그인 성공 시)
$app->post('/login', function ($request, $response) use ($secretKey) {
    $payload = [
        'iss' => 'minstudio.app', // 발급자
        'exp' => time() + 3600,   // 만료시간 (1시간 뒤)
        'uid' => 42               // 유저 고유 ID
    ];
    // HS256 알고리즘으로 서명하여 토큰 생성
    $jwt = JWT::encode($payload, $secretKey, 'HS256');
    
    return jsonResponse($response, ['token' => $jwt]);
});

// 2. 토큰 검증 미들웨어
$jwtMiddleware = function ($request, $handler) use ($secretKey) {
    $authHeader = $request->getHeaderLine('Authorization');
    // "Bearer eyJh..." 형식에서 토큰만 분리
    $token = str_replace('Bearer ', '', $authHeader);

    try {
        // 토큰 해독 및 서명 검증! (위조되거나 만료되면 에러 발생)
        $decoded = JWT::decode($token, new Key($secretKey, 'HS256'));
        
        // 검증 성공 시, 뒷단 라우트에서 유저 ID를 쓸 수 있게 Request에 속성 추가
        $request = $request->withAttribute('user_id', $decoded->uid);
        return $handler->handle($request);
        
    } catch (Exception $e) {
        // 검증 실패 시 돌려보냄
        $res = new \Slim\Psr7\Response();
        $res->getBody()->write(json_encode(['error' => '유효하지 않은 토큰']));
        return $res->withStatus(401)->withHeader('Content-Type', 'application/json');
    }
};

// 3. 보안 구역에 미들웨어 적용
$app->get('/my-data', function ($request, $response) {
    $userId = $request->getAttribute('user_id');
    return jsonResponse($response, ["message" => "환영합니다, {$userId}번 유저님!"]);
})->add($jwtMiddleware);
JWT(JSON Web Token)를 이용한 사용자 인증 | Minstudio