当前位置: 首页 > news >正文

在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工具类

首先确定一些参数

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端的

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

public function init()
{
    $md5 = md5(time());
    return $md5;
}

生成密钥的方法

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);
}

使用样例

$token = Token::createToken(['id' => '1', 'role' => 'admin']);

解析密钥并校验的方法

解析方法
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无效']));
    }
}
验证管理员
public static function isAdmin($token)
{
    $decodeToken = self::decodeToken($token);

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

使用样例

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

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

使用样例

if (!Token::checkSelf($id, $token)) {
    $this->error('权限不足');
}
完整代码
<?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需要额外安装扩展

composer require firebase/php-jwt

相关文章:

  • Crypto加密货币生态构成及较有前景的几个crypto项目
  • uniapp -- 列表垂直方向拖拽drag组件
  • Python第七章05:文件操作综合练习题
  • 游戏引擎学习第198天
  • ②EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关
  • JsonCpp 处理 JSON(现代 C++ 方案)(三)
  • WPF基础知识
  • 关于VUE中v-model响应式失效的问题
  • Spring相关面试题总结
  • docker打包使用有头模式playwright
  • 【开题报告+论文+源码】基于springboot加vue 前后端分离的校园新闻审核发布管理系统
  • 鸿蒙NEXT小游戏开发:记忆翻牌
  • 网络攻防快速入门笔记pwn | 02 栈溢出题型 | 2.3 ret2syscall
  • 【C++进阶四】vector模拟实现
  • 蓝桥杯省模拟赛 数位和
  • 使用LangChain Agents构建Gradio及Gradio Tools(3)——使用Langchain agents构建Gradio UI
  • AI-人工智能-多模态学习助力精准预测心脏毒性
  • 使用Hugging Face训练自定义重排模型(Reranker)完全指南
  • 2024年蓝桥杯Java B组省赛真题超详解析-分布式队列
  • Docker中安装MySQL--------【详细图解】
  • 遍体鳞伤就是击不倒,这是国米老男孩最后的倔强
  • 网商银行2024年年报发布,客户资产管理规模超过1万亿
  • 排除燃气爆炸、人为放火可能,辽宁辽阳火灾事故起火原因正在调查
  • 厚重与潮流交织,淮安展现“运河之都”全新城市想象
  • 华夏银行一季度营收降逾17%、净利降逾14%,公允价值变动损失逾24亿
  • 路边“僵尸车”被人以1450元卖了,嫌疑人被刑拘