Home >PHP Framework >ThinkPHP >Detailed explanation of how to use JWT in thinkphp6.0.7

Detailed explanation of how to use JWT in thinkphp6.0.7

藏色散人
藏色散人forward
2021-12-15 14:51:133386browse

The following thinkphp framework tutorial column will introduce to you how to use JWT in thinkphp6.0.7. I hope it will be helpful to friends in need!

Super detailed explanation of using JWT in thinkphp6.0.7 (including code)

What is JWT

JWT is the abbreviation of json web token. It encrypts user information into the token, and the server does not save any user information. The server verifies the correctness of the token by using the saved key. As long as it is correct, the verification is passed. Token-based authentication can replace the traditional cookie session authentication method.

Session-based login authentication

In traditional user login authentication, because http is stateless, the session method is used. If the user logs in successfully, the server will guarantee a session, and of course will give the client a sessionId. The client will save the sessionId in a cookie, and each request will carry this sessionId.

Cookie session mode is usually stored in memory, and the service will face session sharing problems from single service to multiple services. As the number of users increases, the overhead will increase. This is not the case with JWT. It only requires the server to generate a token, the client to save the token, each request to carry the token, and the server to authenticate and parse it.

JWT consists of three parts: header.payload.signature

Header part:

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

payload part:

    {
      "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唯一标识
    }

signature part:

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

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

JWT usage process

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

jwt version

There is jwt in php Multiple versions: I chose the latest version. Don't ask why, when you buy electronic products, you always buy new ones instead of old ones. Looking at the picture, you can see that version 4.1.0 supports more parameters. The specific parameters will be explained below

Detailed explanation of how to use JWT in thinkphp6.0.7
Installing jwt

1. Use composer to install

composer require lcobucci/jwt

2. Download from github

Click here to jump to the github address:https://github.com/lcobucci/jwt

Dependency

PHP 5.5+
OpenSSL扩展

Use

Parameter explanation

Explain the meaning of the above parameters before using:
Name explanation
iss (issuer) issuer Request entity, can be a request initiator The user's information can also be the issuer of jwt
sub (Subject) Set the subject, similar to the subject when sending an email
aud (audience) The party receiving the jwt
exp (expire) token expiration time
nbf (not before) The current time is before the nbf setting time, the token cannot be used
iat (issued at) token creation time
jti (JWT ID) Set a unique identifier for the current token

How to implement JWT in PHP

I am using PHP 7.3.4, no nonsense, just enter the code, create a new jwt.php, copy and paste as follows:

<?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

The above is the detailed content of Detailed explanation of how to use JWT in thinkphp6.0.7. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:csdn.net. If there is any infringement, please contact admin@php.cn delete