>PHP 프레임워크 >ThinkPHP >thinkphp6.0.7에서 JWT를 사용하는 방법에 대한 자세한 설명

thinkphp6.0.7에서 JWT를 사용하는 방법에 대한 자세한 설명

藏色散人
藏色散人앞으로
2021-12-15 14:51:133386검색

다음 thinkphp프레임워크 튜토리얼 칼럼에서는 thinkphp6.0.7에서 JWT를 사용하는 방법을 소개하겠습니다. 도움이 필요한 친구들에게 도움이 되길 바랍니다!

thinkphp6.0.7에서 JWT 사용에 대한 매우 자세한 설명(코드 포함)

JWT란 무엇입니까

JWT는 json web token의 약어입니다. 사용자 정보를 토큰으로 암호화하며 서버는 사용자 정보를 저장하지 않습니다. 서버는 저장된 키를 사용하여 토큰의 정확성을 확인합니다. 토큰이 정확하면 확인이 통과됩니다. 토큰 기반 인증은 기존 쿠키+세션 인증 방법을 대체할 수 있습니다.

세션 기반 로그인 인증

기존 사용자 로그인 인증에서는 http가 Stateless이기 때문에 세션 방식을 사용합니다. 사용자가 성공적으로 로그인하면 서버는 세션을 보장하고 물론 클라이언트에게 sessionId를 제공합니다. 클라이언트는 sessionId를 쿠키에 저장하고 각 요청은 이 sessionId를 전달합니다.

쿠키+세션 모델은 일반적으로 메모리에 저장되며, 서비스는 단일 서비스에서 여러 서비스로 세션 공유 문제에 직면하게 되며, 사용자 수가 증가하면 오버헤드도 증가하게 됩니다. JWT의 경우에는 그렇지 않습니다. 서버는 토큰을 생성하고, 클라이언트는 토큰을 저장하고, 각 요청은 토큰을 전달하고, 서버는 이를 인증하고 구문 분석해야 합니다.

JWT는 header.payload.signature

세 부분으로 구성됩니다. 헤더 부분:

  {
      "alg": "HS256",
      "typ": "JWT"
    }
对应base64UrlEncode编码为:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
说明:该字段为json格式。alg字段指定了生成signature的算法,默认值为 HS256,typ默认值为JWT

페이로드 부분:

    {
      "sub": "1234567890",
      "name": "John Doe",
      "iat": 1516239022
    }
对应base64UrlEncode编码为:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
说明:该字段为json格式,表明用户身份的数据,可以自己自定义字段,很灵活。sub 面向的用户,name 姓名 ,iat 签发时间。例如可自定义示例如下:
  {
        "iss": "admin",           //该JWT的签发者
        "sub": "www.admin.com",   //面向的用户
        “aud”: "zhangsan",        //接收jwt的一方
        "iat": 1535967430,        //签发时间
        "exp": 1535974630,        //过期时间
        "nbf": 1535967430,        //该时间之前不接收处理该Token 
        "jti": "9f10e796726e332cec401c569969e13e"   //该Token唯一标识
    }

서명 부분:

    HMACSHA256(
      base64UrlEncode(header) + "." +
      base64UrlEncode(payload),
      123456
    )
对应的签名为:keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU

最终得到的JWT的Token为(header.payload.signature):eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU
说明:对header和payload进行base64UrlEncode编码后进行拼接。通过key(这里是123456)进行HS256算法签名。

JWT 사용 프로세스

初次登录:用户初次登录,输入用户名密码
密码验证:服务器从数据库取出用户名和密码进行验证
生成JWT:服务器端验证通过,根据从数据库返回的信息,以及预设规则,生成JWT
返还JWT:服务器的HTTP RESPONSE中将JWT返还
带JWT的请求:以后客户端发起请求,HTTP REQUEST
HEADER中的Authorizatio字段都要有值,为JWT
服务器验证JWT

jwt 버전

PHP에는 여러 버전의 jwt가 있습니다. 저는 최신 버전을 선택했습니다. 왜 전자 제품을 구입할 때 항상 오래된 제품 대신 새 제품을 구입하는지 묻지 마십시오. 그림을 보면 버전 4.1.0이 더 많은 매개변수를 지원하는 것을 알 수 있습니다. 구체적인 매개변수는 아래에 설명되어 있습니다

thinkphp6.0.7에서 JWT를 사용하는 방법에 대한 자세한 설명
jwt 설치

1. 작곡가를 사용하여 설치하세요

composer require lcobucci/jwt

2.github에서 다운로드하세요

github 주소로 이동하려면 저를 클릭하세요:https :// github.com/lcobucci/jwt

에 따라 다름

PHP 5.5+
OpenSSL扩展

Use

매개변수 설명

사용하기 전에 위 매개변수의 의미를 설명하세요.
이름 설명
iss(발행자) 발급자를 요청하는 엔터티입니다. 요청을 시작한 사용자여야 합니다. 정보는 jwt의 발행자가 될 수도 있습니다.
sub(제목) 이메일을 보낼 때 제목과 유사하게 제목을 설정합니다.
aud(청중) jwt
exp(만료) 토큰 만료를 받는 당사자 time
nbf (이전 아님) 현재 시간은 nbf 설정 시간 이전에는 토큰을 사용할 수 없습니다
iat(발행) 토큰 생성 시간
jti(JWT ID) 현재 토큰의 고유 식별자를 설정합니다

방법 PHP에서 JWT를 구현하려면

저는 PHP 7.3.4를 사용하고 있습니다. 말도 안 돼요. 코드로 이동하여 새 jwt.php를 만들고 다음과 같이 복사하여 붙여넣으세요.

<?php /**
 * PHP实现jwt
 */
class Jwt {
 
    //头部
    private static $header=array(
        &#39;alg&#39;=>'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;
 
        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 class="brush:php;toolbar:false">";
    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 class="brush:php;toolbar:false">";
    echo $token_test;
    
    //对token进行验证签名
    $getPayload_test=Jwt::verifyToken($token_test);
    echo "<br><br>";
    var_dump($getPayload_test);
    echo "<br><br>";
    //自己使用时候end

위 내용은 thinkphp6.0.7에서 JWT를 사용하는 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제