php 구현 JWT(json web token)인증 사례 상세 설명

7901 단어 phpJWT감 권
JWT 가 뭐 예요?
JWT 는 json web token 의 줄 임 말이다.이 는 사용자 정 보 를 token 에 암호 화하 고 서버 는 사용자 정 보 를 저장 하지 않 습 니 다.서버 는 저 장 된 키 를 사용 하여 token 의 정확성 을 검증 합 니 다.정확 하면 검증 을 통과 합 니 다.token 기반 인증 은 전통 적 인 쿠키+session 인증 방법 을 대체 할 수 있 습 니 다.
JWT 는 세 부분 으로 구성 되 어 있 습 니 다:header.payload.signature
아래 의 예 는 JWT 홈 페이지 을 예 로 들 면
헤더 부분:

{
 "alg": "HS256",
 "typ": "JWT"
}
대응 base64UrlEncode 인 코딩:eyJhbGCIJIUzI1NiIsInR5cCI6IkpXVCJ 9
설명:이 필드 는 json 형식 입 니 다.alg 필드 에서 signature 를 만 드 는 알고리즘 을 지 정 했 습 니 다.기본 값 은 HS 256 이 고,typ 기본 값 은 JWT 입 니 다.
payload 부분:

{
 "sub": "1234567890",
 "name": "John Doe",
 "iat": 1516239022
}
base64UrlEncode 에 대응 하 는 인 코딩 은 eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2mjM5MDIyfQ 입 니 다.
설명:이 필드 는 json 형식 으로 사용자 의 신분 을 나타 내 는 데이터 로 필드 를 사용자 정의 할 수 있 고 유연 합 니 다.sub 대상 사용자,name 이름,iat 서명 시간.예 를 들 어 다음 과 같이 사용자 정의 예제 가 있 습 니 다.

{
  "iss": "admin",     // JWT    
  "iat": 1535967430,    //    
  "exp": 1535974630,    //    
  "nbf": 1535967430,     //           Token
  "sub": "www.admin.com",  //     
  "jti": "9f10e796726e332cec401c569969e13e"  // Token    
}

signature 부분:

HMACSHA256(
 base64UrlEncode(header) + "." +
 base64UrlEncode(payload),
 123456
) 
대응 하 는 서명 은:keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr6ZOwU
최종 적 으로 얻 은 JWT 의 Token 은(header.payload.signature):eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ 9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTe2MJM5M5MDIyfQ.keH6T3x1z7mmhKL1T3r9sQdAxB6siemGMr6ZOwU
설명:header 와 payload 를 base64UrlEncode 인 코딩 한 후 연결 합 니 다.key(여 기 는 123456)를 통 해 HS 256 알고리즘 서명 을 진행 합 니 다.
JWT 사용 절차
  • 첫 로그 인:사용자 첫 로그 인,사용자 이름 비밀번호 입력
  • 암호 검증:서버 가 데이터베이스 에서 사용자 이름과 비밀 번 호 를 꺼 내 서
  • 을 검증 합 니 다.
  • 생 성 JWT:서버 측 검증 통과,데이터베이스 에서 돌아 오 는 정보 및 미리 설 정 된 규칙 에 따라 JWT
  • 생 성
  • JWT 반환:서버 의 HTTP RESPONSE 에서 JWT 를
  • 반환
  • JWT 요청:이후 클 라 이언 트 요청,HTTP REQUEST
  • HEADER 의 Authorizatio 필드 는 모두 값 이 있어 야 합 니 다.JWT
  • 입 니 다.
  • 서버 검증 JWT
  • PHP 는 어떻게 JWT 를 실현 합 니까?
    저 자 는 PHP 7.0.31 을 사용 합 니 다.쓸데없는 말 없 이 코드 를 직접 올 리 고 jwt.php 를 새로 만 듭 니 다.복사 붙 여 넣 기 는 다음 과 같 습 니 다.
    
    <?php
    /**
     * PHP  jwt
     */
    class Jwt {
    
      //  
      private static $header=array(
        'alg'=>'HS256', //  signature   
        'typ'=>'JWT'  //  
      );
    
      //  HMAC             
      private static $key='123456';
    
      /**
       *   jwt token
       * @param array $payload jwt           
       * [
       * 'iss'=>'jwt_admin', // JWT    
       * 'iat'=>time(), //    
       * 'exp'=>time()+7200, //    
       * 'nbf'=>time()+60, //           Token
       * 'sub'=>'www.admin.com', //     
       * 'jti'=>md5(uniqid('JWT').time()) // Token    
       * ]
       * @return bool|string
       */
      public static function getToken(array $payload)
      {
        if(is_array($payload))
        {
          $base64header=self::base64UrlEncode(json_encode(self::$header,JSON_UNESCAPED_UNICODE));
          $base64payload=self::base64UrlEncode(json_encode($payload,JSON_UNESCAPED_UNICODE));
          $token=$base64header.'.'.$base64payload.'.'.self::signature($base64header.'.'.$base64payload,self::$key,self::$header['alg']);
          return $token;
        }else{
          return false;
        }
      }
    
      /**
       *   token    ,    exp,nbf,iat  
       * @param string $Token      token
       * @return bool|string
       */
      public static function verifyToken(string $Token)
      {
        $tokens = explode('.', $Token);
        if (count($tokens) != 3)
          return false;
    
        list($base64header, $base64payload, $sign) = $tokens;
    
        //  jwt  
        $base64decodeheader = json_decode(self::base64UrlDecode($base64header), JSON_OBJECT_AS_ARRAY);
        if (empty($base64decodeheader['alg']))
          return false;
    
        //    
        if (self::signature($base64header . '.' . $base64payload, self::$key, $base64decodeheader['alg']) !== $sign)
          return false;
    
        $payload = json_decode(self::base64UrlDecode($base64payload), JSON_OBJECT_AS_ARRAY);
    
        //                 
        if (isset($payload['iat']) && $payload['iat'] > time())
          return false;
    
        //                 
        if (isset($payload['exp']) && $payload['exp'] < time())
          return false;
    
        // nbf          Token
        if (isset($payload['nbf']) && $payload['nbf'] > time())
          return false;
    
        return $payload;
      }
    
      /**
       * base64UrlEncode  https://jwt.io/  base64UrlEncode    
       * @param string $input         
       * @return string
       */
      private static function base64UrlEncode(string $input)
      {
        return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
      }
    
      /**
       * base64UrlEncode https://jwt.io/  base64UrlEncode    
       * @param string $input         
       * @return bool|string
       */
      private static function base64UrlDecode(string $input)
      {
        $remainder = strlen($input) % 4;
        if ($remainder) {
          $addlen = 4 - $remainder;
          $input .= str_repeat('=', $addlen);
        }
        return base64_decode(strtr($input, '-_', '+/'));
      }
    
      /**
       * HMACSHA256    https://jwt.io/  HMACSHA256    
       * @param string $input  base64UrlEncode(header).".".base64UrlEncode(payload)
       * @param string $key
       * @param string $alg      
       * @return mixed
       */
      private static function signature(string $input, string $key, string $alg = 'HS256')
      {
        $alg_config=array(
          'HS256'=>'sha256'
        );
        return self::base64UrlEncode(hash_hmac($alg_config[$alg], $input, $key,true));
      }
    }
    
      //         begin
      $payload=array('sub'=>'1234567890','name'=>'John Doe','iat'=>1516239022);
      $jwt=new Jwt;
      $token=$jwt->getToken($payload);
      echo "<pre>";
      echo $token;
    
      // token      
      $getPayload=$jwt->verifyToken($token);
      echo "<br><br>";
      var_dump($getPayload);
      echo "<br><br>";
      //         end
    
      //      begin
      $payload_test=array('iss'=>'admin','iat'=>time(),'exp'=>time()+7200,'nbf'=>time(),'sub'=>'www.admin.com','jti'=>md5(uniqid('JWT').time()));;
      $token_test=Jwt::getToken($payload_test);
      echo "<pre>";
      echo $token_test;
    
      // token      
      $getPayload_test=Jwt::verifyToken($token_test);
      echo "<br><br>";
      var_dump($getPayload_test);
      echo "<br><br>";
      //      end
    
    
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기