在Thinkphp中使用JWT 包括JWT是什么,JWT的优势

首先了解一下什么是JWT

JWT 是一种开放标准(RFC 7519),用于在各方之间以 JSON 对象形式安全传输信息4。其核心特点包括:

复制代码
结构:由三部分组成(Header、Payload、Signature),通过点号分隔,例如 xxxxx.yyyyy.zzzzz2。
	Header:声明加密算法和 Token 类型(如 HS256)。
	Payload:包含用户信息、注册声明(如 iss、exp)和自定义数据。
	Signature:通过密钥对前两部分签名,确保数据完整性。
用途:
	身份认证:用户登录后,服务端生成 JWT 返回客户端,客户端后续请求携带 JWT 以访问受保护资源1。

JWT的优势

  1. 无状态性

    复制代码
    优势:JWT 自身包含用户身份和权限信息,服务端无需存储会话数据(如 Session),直接通过验证 Token 签名即可完成认证。
    效果:降低服务端资源消耗,天然支持分布式系统和横向扩展。
    对比:传统 Session 需要服务端维护会话状态,多服务器场景需共享 Session 存储(如 Redis),增加复杂度。
  2. 跨域支持

    复制代码
    优势:JWT 通过 HTTP 头(如 Authorization: Bearer <token>)传递,不受 Cookie 同源策略限制。
    应用场景:适合前后端分离、跨域 API 调用及微服务架构。
    对比:Cookie 需额外配置 CORS 策略,且存在跨域限制。
  3. 安全性增强

    复制代码
    优势:防 CSRF:Token 存储在客户端而非 Cookie,避免跨站请求伪造攻击。
    防篡改:签名机制(如 HS256)确保 Token 内容完整性和来源可信。
  4. 标准化与灵活性

    复制代码
    优势:JWT 遵循 RFC 7519 标准,支持多种签名算法(如 RSA、HMAC)和自定义声明(Claims),便于集成第三方服务。
    扩展场景:单点登录(SSO)、API 网关鉴权等。

搭建JWT工具类

首先确定一些参数

php 复制代码
private static $key = '4875c029de194dd79ade2ee5aa68ee57';//密钥
private const exp = 3600;//token过期时间 1小时
private const alg = 'HS256';//加密算法
private const iss = 'ceshi';// 签发人
private const aud = 'web';// 受众   

密钥可以自己随便写,但是建议不要太简单

签发人一般是用于校验该token是不是自己的

受众一般是用于区分web和app端的

密钥可以使用下面代码生成一个

php 复制代码
public function init()
{
    $md5 = md5(time());
    return $md5;
}

生成密钥的方法

php 复制代码
public static function createToken($data)
{
   $time = time();
   $payload = [
       "iat" => $time, // 签发时间
       "nbf" => $time, // 生效时间
       "exp" => self::exp + $time, // 失效时间
       "iss" => self::iss,// 签发人
       "aud" => self::aud,// 受众
       "data" => $data, // 自定义数据
   ];
   return JWT::encode($payload, self::$key, self::alg);
}

使用样例

php 复制代码
$token = Token::createToken(['id' => '1', 'role' => 'admin']);

解析密钥并校验的方法

解析方法
php 复制代码
private static function decodeToken($token)
{
    try {
        return JWT::decode($token, new Key(self::$key, self::alg));
    } catch (\Exception $e) {
        throw new HttpResponseException(json(['code' => 401, 'msg' => 'token无效']));
    }
}
验证管理员
php 复制代码
public static function isAdmin($token)
{
    $decodeToken = self::decodeToken($token);

    return $decodeToken->data->role === 'admin';
}

使用样例

php 复制代码
if (!Token::isAdmin($token)) {
    $this->error('权限不足');
}
验证是否为本人token
php 复制代码
public static function checkSelf($userId, $token)
{
     $decodeToken = self::decodeToken($token);

     return $decodeToken->data->id == $userId;
 }

使用样例

php 复制代码
if (!Token::checkSelf($id, $token)) {
    $this->error('权限不足');
}
完整代码
php 复制代码
<?php

namespace app\common\library;//这个命名空间记得要换成自己的

use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use think\exception\HttpResponseException;

class Token
{
    private static $key = '4875c029de194dd79ade2ee5aa68ee57';//密钥
    private const exp = 3600;//token过期时间 1小时
    private const alg = 'HS256';//加密算法
    private const iss = 'ceshi';// 签发人
    private const aud = 'web';// 受众

    public static function createToken($data)
    {
        $time = time();
        $payload = [
            "iat" => $time, // 签发时间
            "nbf" => $time, // 生效时间
            "exp" => self::exp + $time, // 失效时间
            "iss" => self::iss,// 签发人
            "aud" => self::aud,// 受众
            "data" => $data, // 自定义数据
        ];
        return JWT::encode($payload, self::$key, self::alg);
    }

    public static function isAdmin($token)
    {
        $decodeToken = self::decodeToken($token);

        return $decodeToken->data->role === 'admin';
    }

    public static function checkSelf($userId, $token)
    {
        $decodeToken = self::decodeToken($token);

        return $decodeToken->data->id == $userId;
    }


    private static function decodeToken($token)
    {
        try {
            return JWT::decode($token, new Key(self::$key, self::alg));
        } catch (\Exception $e) {
            throw new HttpResponseException(json(['code' => 401, 'msg' => 'token无效']));
        }
    }


}

使用JWT需要额外安装扩展

php 复制代码
composer require firebase/php-jwt
相关推荐
BingoGo10 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack10 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo1 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack1 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack3 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
QQ5110082854 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php
WeiXin_DZbishe4 天前
基于django在线音乐数据采集的设计与实现-计算机毕设 附源码 22647
javascript·spring boot·mysql·django·node.js·php·html5