php에서 JsonWebToken(JWT) 간단하게 사용하기 (php-ezJWT)

ruwaku·2021년 7월 21일
0

JWT에 대해 간단히 짚고 넘어가기

JsonWebToken(JWT)란, 무결성을 보장하는 웹 토큰 시스템입니다.

JWT는 아무나 해독할 수 있습니다. 따라서 토큰에는 공개되어도 괜찮은 정보만을 넣어야 합니다.
(토큰 해독은 쉽게 가능하지만, 토큰 조작은 불가능해서 무결성을 보장하는 것이죠.)

php-ezJWT

php에서 JWT를 사용하고 싶어서 10여시간 삽질한 결과.... 이렇게 간단한 라이브러리를 직접 만들었답니다.
코드는 정말 간단합니다. 기능이 sign, validate 밖에 없어요. 간단한 사용자 인증 등에 요긴합니다.
최대한 안전하게 짠다고 짠 코든데 적극적인 피드백 부탁드려요 🙇‍

유의사항

  • base64_encode()는 JWT의 문법을 충족시킬 수 없습니다. 이를 해결하기 위해 base64UrlEncode/base64UrlDecode (encode/decode로 축약하였음) 메서드를 만들어서 사용했습니다.

코드

<?php
class ezJWT {
  /*
    < php-ezJWT >
    by Ruwaku (zpci5686@naver.com)
    freely editable. 자유롭게 수정 가능.
  */
  protected $secret_key;
  function __construct() {
    $this->secret_key = "!!! YOUR SECRET KEY !!!";
  }
  function encode($data) {
    return str_replace(["+", "/", "="], ["-", "_", ""], base64_encode($data));
  }
  function decode($data) {
    return base64_decode(str_pad(strtr($data, "-_", "+/"), strlen($data) % 4, "=", STR_PAD_RIGHT));
  }
  function sign(array $data) {
    $encoded_header = $this->encode(
      json_encode([
        "alg" => "HS256",
        "typ" => "JWT",
      ])
    );
    $encoded_payload = $this->encode(json_encode($data));
    $encoded_signature = $this->encode(
      hash_hmac("sha256", $encoded_header.".".$encoded_payload), $this->secret_key, true)
    );
    return $encoded_header.".".$encoded_payload.".".$encoded_signature;
  }
  function validate($token) {
    $part = explode(".", $token);
    $encoded_header = $part[0];
    $encoded_payload = $part[1];
    $encoded_signature = $part[2];

    //signature verify
    if ($this->encode(hash_hmac("sha256", $encoded_header.".".$encoded_payload, $this->secret_key, true)) ===
      $encoded_signature) {
      return json_decode($this->decode($encoded_payload), true);
    } else {
      return false;
    }
  }
}
?>

사용 방법

사용하기 전 secret_key를 본인이 원하는대로 설정해주세요. 이 키로 token 암호화가 진행되므로 유출되지 않게 주의해주시고요.

그런 다음 ezJWT의 인스턴스를 생성합니다. ezJWT의 메서드는 아래와 같습니다.

ezJWT의 메서드

sign(array)

sign 메서드는 토큰을 만들어 반환합니다.

  1. header, payload, signature 알맞게 생성
  2. 각각을 base64UrlEncode 함
  3. JWT 문법에 맞게 하나의 문자열로 합쳐서 return

validate(token)

validate 메서드는 인자로 받은 토큰의 검증을 성공한 경우 토큰의 payload를 반환하고, 실패한 경우 false를 반환합니다.

  1. JWT 문법에 따라 header, payload, signature를 제 위치에서 가져옴
  2. 토큰 signature가 올바른지 검증
  3. signature가 올바르다면 return payload / 올바르지 않다면 return false (token 조작 의심)

사용 예제

아래 코드를 참고하세요.

$jwtInstance = new ezJWT();
$token = $jwtInstance->sign([
  "login_type" => "kakao",
  "login_pdr_token" => "asdf",
]);
$payload = $jwtInstance->validate($token);
echo $token; // 토큰 출력
echo $payload; // { "login_type": "kakao", "login_pdr_token": "asdf" } 출력

한번 jwt.io에서 올바른 JWT인지 검증 해 보세요. 😊👍 올바르다고 나오네요!

여담

  • 사실 저는 글을 쓸 때, 맞춤법에 집착하는 경향이 있는데요. 이번 글을 쓰다보니 method라는 단어가 많이 나오더라고요. "메소드? 메서드?" 긴가민가해서 검색해보았는데 "메서드"가 올바른 표기라고 합니다. 😮
  • 제가 필요해서 만든건데 만족도가 매우 높아서 공유합니다. ❤️
profile
고등학교 1학년 개발자 이야기

0개의 댓글