Rumah >rangka kerja php >ThinkPHP >Penjelasan terperinci tentang cara menggunakan JWT dalam thinkphp6.0.7

Penjelasan terperinci tentang cara menggunakan JWT dalam thinkphp6.0.7

藏色散人
藏色散人ke hadapan
2021-12-15 14:51:133389semak imbas

Lajur tutorial rangka kerja thinkphp berikut akan memperkenalkan kepada anda cara menggunakan JWT dalam thinkphp6.0.7 Saya harap ia dapat membantu rakan yang memerlukan.

Penjelasan yang sangat terperinci tentang penggunaan JWT dalam thinkphp6.0.7 (termasuk kod)

Apakah itu JWT

JWT ialah singkatan kepada json web token. Ia menyulitkan maklumat pengguna ke dalam token, dan pelayan tidak menyimpan sebarang maklumat pengguna. Pelayan mengesahkan ketepatan token dengan menggunakan kunci yang disimpan Selagi ia betul, pengesahan diluluskan. Pengesahan berasaskan token boleh menggantikan kaedah pengesahan sesi kuki tradisional.

Pengesahan log masuk berasaskan sesi

Dalam pengesahan log masuk pengguna tradisional, kerana http adalah tanpa status, kaedah sesi digunakan. Jika pengguna berjaya log masuk, pelayan akan menjamin sesi, dan sudah tentu akan memberikan pelanggan sessionId Pelanggan akan menyimpan sessionId dalam kuki, dan setiap permintaan akan membawa sessionId ini.

Mod sesi kuki biasanya disimpan dalam memori, dan perkhidmatan akan menghadapi masalah perkongsian sesi daripada perkhidmatan tunggal kepada berbilang perkhidmatan Apabila bilangan pengguna bertambah, overhed akan meningkat. Ini tidak berlaku dengan JWT Ia hanya memerlukan pelayan untuk menjana token, pelanggan untuk menyimpan token, setiap permintaan untuk membawa token, dan pelayan untuk mengesahkan dan menghuraikannya.

JWT terdiri daripada tiga bahagian: header.payload.signature

bahagian header:

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

bahagian muatan:

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

bahagian tandatangan:

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

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

Proses penggunaan JWT

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

versi jwt

Terdapat berbilang versi jwt dalam php: Saya memilih versi terkini. Jangan tanya mengapa, apabila anda membeli produk elektronik, anda sentiasa membeli yang baru dan bukannya yang lama. Melihat pada gambar, anda dapat melihat bahawa versi 4.1.0 menyokong lebih banyak parameter. Parameter khusus akan diterangkan di bawah

Penjelasan terperinci tentang cara menggunakan JWT dalam thinkphp6.0.7
Pasang jwt

1. Gunakan komposer untuk memasang

komposer memerlukan lcobucci/jwt.

2. Muat turun dari github

Klik di sini untuk melompat ke alamat github: https://github.com/lcobucci/jwt

Pergantungan

PHP 5.5+
OpenSSL扩展

Gunakan

Penjelasan parameter

Terangkan maksud parameter di atas sebelum menggunakannya:
Penjelasan nama
entiti permintaan penerbit iss (pengeluar) , yang boleh menjadi Maklumat pengguna yang memulakan permintaan juga boleh menjadi pengeluar jwt
sub (Subjek) menetapkan subjek, serupa dengan subjek semasa menghantar e-mel
audiens (khalayak) pihak yang menerima jwt
exp (expire) token tamat Masa
nbf (bukan sebelum) Masa semasa adalah sebelum masa penetapan nbf, token tidak boleh digunakan
iat (dikeluarkan pada) masa penciptaan token
jti (ID JWT) Tetapkan pengecam unik untuk token semasa

Cara melaksanakan JWT dalam PHP

Saya menggunakan PHP 7.3.4, bukan omong kosong, hanya pergi ke kod, buat jwt.php baharu, salin dan tampal seperti berikut:

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

Atas ialah kandungan terperinci Penjelasan terperinci tentang cara menggunakan JWT dalam thinkphp6.0.7. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:csdn.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam