thinkphp6 JWT报错 ‘“kid“ empty, unable to lookup correct key‘解决办法

news2025/4/3 12:12:43

文章目录

    • JWT简介
    • 安装
    • 问题
    • 先前的代码
    • 解决办法
    • 修改后的完整代码

JWT简介

JWT全称为Json Web
Token,是一种用于在网络应用之间传递信息的简洁、安全的方式。JWT标准定义了一种简洁的、自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。由于它的简洁性、可扩展性和可传递性,成为当前最流行的跨域身份验证解决方案之一。一般来说,JWT会被用来在客户端和服务端之间传递一些敏感信息,比如用户认证信息、权限信息等等。

安装

thinkphp框架默认不带这个依赖包,需要自己安装

composer require firebase/php-jwt

使用的时候直接use即可

use \Firebase\JWT\JWT;

问题

thinkphp6使用JWT报错 ‘“kid“ empty, unable to lookup correct key‘
这个玩意简直就是一个大坑,弄了一个早上
下面是报错的内容
在这里插入图片描述
遇到这个问题我也很无语
最后发现是JWT包的encode 和 decode 和之前的有区别

先前的代码

 public function index()
    {
        $username = Request::post('username');
        $password = Request::post('password');
        $user = User::where('username', $username)->find();
        if (!$user) {
            return json([
                'code' => 401,
                'message' => '用户名错误,请重试',
                'data' => null
            ]);
        }
        if ($user->password !== md5($password)) {
            return json([
                'code' => 401,
                'message' => '密码错误,请重试',
                'data' => null
            ]);
        }
        // 生成 token
        $key = '147258369'; // 生成 token 的秘钥
        $payload = array(
            // "iss" => "http://127.0.0.1:8000",  // JWT的签发者
            // "aud" => "http://127.0.0.1:9528/",  // JWT的接收者可以省略
            "iat" => time(),  // token 的创建时间
            "nbf" =>  time(),  // token 的生效时间
            "exp" => time() + 3600,  // token 的过期时间
            "data" => [
                // 包含的用户信息等数据
                "username" => $username,
                "permission"=>$user->permission
            ]
        );
        $jwt = JWT::encode($payload, $key,'HS256');
        return json([
            'code' => 200,
            'message' => '登录成功',
            'token' => $jwt,
            'data' => [
                'id' => $user->id,
                'username' => $user->username,
                'permission' => $user->permission,
            ]
        ]);
    }

这是获取用户信息的方法
同时包含了对JWT字符串进行解析的操作

 public function getInfo(){
        $key = '147258369';
        $token = Request::get('token'); // 需要验证的 Token 字符串

            $decoded = JWT::decode($token,$key,['HS256']);// 解码并验证 Token
            if(!$decoded) return json([
                
                    'code' => 401,
                    'message' => 'token无效',
                    'data' => null
            ]);
            // 如果 Token 有效,$decoded 会包含解码后的数据
            $username = $decoded->data->username;
            $permission = $decoded->data->permission;
            // 验证通过,执行相应操作
                return json([
                'code' => 200,
                'message' => '获取用户信息成功',
                'data' => [
                    'username' => $username,
                    'permission' => $permission,
                ]
            ]);
        }

乍一看好像没什么问题,是的换做以前确实没有问题,但是现在这种写法好像用不了

解决办法

只需要在生成JWT的时候添加一个keyId
具体内容如下

$keyId = "keyId";
 $jwt = JWT::encode($payload, $key,'HS256',$keyId);

在解析的时候key要用new Key的方法

use Firebase\JWT\Key;

$key = new Key('key', 'HS256');
$decode = JWT::decode($token, $key);

修改后的完整代码

重点就是生成JWT的时候要记得加上keyId
在解析的时候key要用new Key的方法

生成JWT

<?php
namespace app\controller;

use app\BaseController;
use think\facade\Request;
use app\model\User;
use \Firebase\JWT\JWT;

class Login extends BaseController
{
    public function index()
    {
        $username = Request::post('username');
        $password = Request::post('password');
        $user = User::where('username', $username)->find();
        if (!$user) {
            return json([
                'code' => 401,
                'message' => '用户名错误,请重试',
                'data' => null
            ]);
        }
        if ($user->password !== md5($password)) {
            return json([
                'code' => 401,
                'message' => '密码错误,请重试',
                'data' => null
            ]);
        }
        // 生成 token
        $key = '147258369'; // 生成 token 的秘钥
        $payload = array(
            // "iss" => "http://127.0.0.1:8000",  // issuer
            // "aud" => "http://example.com",  // audience
            "iat" => time(),  // token 的创建时间
            "nbf" =>  time(),  // token 的生效时间
            "exp" => time() + 3600,  // token 的过期时间
            "data" => [
                // 包含的用户信息等数据
                "username" => $username,
                "permission"=>$user->permission
            ]
        );
        $keyId = "keyId"; //这个东西必须要加上,不加上,报错,报错内容:'"kid" empty, unable to lookup correct key'
        $jwt = JWT::encode($payload, $key,'HS256',$keyId);
        return json([
            'code' => 200,
            'message' => '登录成功',
            'token' => $jwt,
            'data' => [
                'id' => $user->id,
                'username' => $user->username,
                'permission' => $user->permission,
            ]
        ]);
    }
}

解析JWT

<?php
namespace app\controller;
use app\BaseController;
use think\facade\Request;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

class User extends BaseController{
    public function getInfo(){
        $key = new Key('147258369', 'HS256');   // 密钥
        // $key = '147258369';
        $token = Request::get('token'); // 需要验证的 Token 字符串

            $decoded = JWT::decode($token,$key);// 解码并验证 Token
            if(!$decoded) return json([
                
                    'code' => 401,
                    'message' => 'token无效',
                    'data' => null
            ]);
            // 如果 Token 有效,$decoded 会包含解码后的数据
            $username = $decoded->data->username;
            $permission = $decoded->data->permission;
            // 验证通过,执行相应操作
                return json([
                'code' => 200,
                'message' => '获取用户信息成功',
                'data' => [
                    'username' => $username,
                    'permission' => $permission,
                ]
            ]);
        }
}

完结!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/482476.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[论文笔记] In Search of an Understandable Consensus Algorithm (Extended Version)

In Search of an Understandable Consensus Algorithm (Extended Version) 寻找可理解的共识算法 (扩展版) [Extended Paper] [Original Paper] ATC’14 (Original) 摘要 Raft 是一个用于管理复制日志的共识算法. Raft 更易于理解, 且为构建实际的系统提供了更好的基础. Raf…

apache hive release notes

hive release notes位置 https://github.com/apache/hive/blob/master/RELEASE_NOTES.txt 如何查看不同版本的release note

计算机是如何工作的

一、冯诺依曼体系&#xff1a; CPU中央处理器&#xff08;运算器控制器&#xff09;&#xff1a;CPU是计算机最核心的部分&#xff0c;进行算数运算和逻辑判断。CPU最重要的指标是“主频”&#xff0c;如&#xff1a;2.5Ghz&#xff0c;描述了CPU的运算速度&#xff0c;可以近…

【React】redux和React-redux

&#x1f380;个人主页&#xff1a;努力学习前端知识的小羊 感谢你们的支持&#xff1a;收藏&#x1f384; 点赞&#x1f36c; 加关注&#x1fa90; Redux和React-redux reduxredux的使用Redux的工作流Redux APIstoreactionreducerstore.dispatch()redux的方法使用 React-Redux…

python人工智能【隔空手势控制鼠标】“解放双手“

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

【计算机图形学基础教程】MFC上机操作步骤

MFC上机操作步骤 步骤1 在Visual Studio界面&#xff0c;选择文件-新建-项目&#xff1a; 步骤2 在新建项目对话框&#xff0c;选择MFC-MFC应用程序&#xff1a; 步骤3 创建一个带有下列特征的新控制台工程框架&#xff0c;主要内容如下&#xff1a; 基于Win32的单文档…

PMP/高项 05-项目进度管理

项目进度管理 概念 项目进度管理&#xff08;Schedule Management) 项目进度管理又叫项目工期管理&#xff08;Duration Management)或项目的时间管理(Time Management) 是一种为管理项目按时完成项目所需的各个过程 进度管理过程 规划进度管理 定义活动 排列活动顺序 估算活…

前端web3入门脚本五:decode input data

一、前言 作为一个前端&#xff0c;在调用合约调试的时候&#xff0c;在区块浏览器里拿到一串 hex 格式的 input data&#xff0c;我们应该怎么decode呢&#xff1f; 二、举例 解码交易需要拥有 对应合约的 abi 以及 input data 下面举例介绍怎么获得这两个信息&#xff1a; 参…

二叉搜索树中的众数

1题目 给你一个含重复值的二叉搜索树&#xff08;BST&#xff09;的根节点 root &#xff0c;找出并返回 BST 中的所有 众数&#xff08;即&#xff0c;出现频率最高的元素&#xff09;。 如果树中有不止一个众数&#xff0c;可以按 任意顺序 返回。 假定 BST 满足如下定义&…

存储资源调优技术——智能缓存分区

SmartPratition智能缓存分区 基本概念 本质上就是一种Cache分区技术 通过对系统核心资源的分区&#xff08;隔离不同业务所需要的缓存资源&#xff09;&#xff0c;保证关键应用的性能 工作原理 用户可以以LUN或文件系统为单位设置SmartPartition分区 每个SmartPartition分区的…

Qt文件系统源码分析—第二篇QSaveFile

范围 深度 首先指定深度分析深度&#xff0c;否者会陷入代码海洋之中。 本文只分析到Win32 API/Windows Com组件/STL库函数层次&#xff0c;再下层代码不做探究 本文主要了解QSaveFile及其具体实现&#xff0c;使用到父类数据的地方只讨论关键点 QT Private类 大部分Qt类有…

基础篇-设计模式

单例模式&#xff1a; 注意&#xff1a;这里的唯一实例不是使用时候才创建,而是构造时候就会创建; 注意&#xff1a;提前创建了对象&#xff0c;并不是调用时候才创建 解决方法&#xff1a; 枚举饿汉单例&#xff1a; 注意: 饿汉式枚举不会通过反序列化破坏单例 懒汉模式&…

SQL笔记(3)——MySQL数据类型

学习MySQL&#xff0c;通常应该是先学习数据类型的&#xff0c;因为不管是开发还是MySQL中&#xff0c;每个数据对象都有其对应的数据类型&#xff0c;MySQL提供了丰富的数据类型&#xff0c;如在创建表的时候就需要指定列的数据类型&#xff0c;在向表中插入数据时&#xff0c…

ElasticSearch(一)下载及安装(windows)

1. 官网 ElasticSearch官网地址ElasticSearch生态组件下载地址Kibana下载地址ik中文分词插件 备注&#xff1a;网址打不开&#xff0c;或者打开速度慢是正常情况。 2. 解压后目录结构 bin &#xff1a;脚本文件&#xff0c;包括启动elasticsearch&#xff0c;安装插件&#…

目录打开显示提示文件或目录损坏且无法读取、文件或目录损坏且无法读取的破解之道

咱们在平日工作时&#xff0c;通常都会将资料放进不同的目录中&#xff0c;方便咱们找到&#xff0c;随着时间的推移就会产生有越来越多目录。最近有位用户了这样一个问题&#xff0c;就是目录无论怎么都无法打开&#xff0c;这样就无法浏览、使用里面的资料了&#xff0c;影响…

springboot sharding-jdbc 主从 读写分离

目录 1 mysql 主从搭建 1.1 docker mysql 主从搭建 1.2 非docker mysql 主从搭建 2 springboot sharding-jdbc 主从 读写分离 2.1 pom 加依赖 2.1 yml 配置文件 3 测试 -> 直接使用 就是读写分离 3.1 实体类User -> 数据字段 对象字典 3.2 Mapper -> 增删改查…

Nomogram | 盘点一下绘制列线图的几个R包!~(二)

1写在前面 不知道各位小伙伴的五一假期过的在怎么样&#xff0c;可怜的我感冒了。&#x1f637; 今天继续之前没有写完的列线图教程吧&#xff0c;再介绍几个制作列线图的R包。&#x1f920; 2用到的包 rm(list ls())library(tidyverse)library(survival)library(rms)library(…

新闻文本关键词提取有哪些算法,这些算法的特点以及应用,以及不足方面的解决办法

目录 一、新闻文本关键词提取算法 1. TF-IDF&#xff08;Term Frequency-Inverse Document Frequency&#xff09;算法 2. TextRank算法 3. 词向量算法 4. 深度学习算法 5. 主题模型算法 二、这些算法的不足方面的解决办法 1. TF-IDF算法&#xff1a; 2. TextRank算法&…

一文彻底读懂nginx中的location指令

Nginx主配置文件结构 location 介绍 location是Nginx中的块级指令(block directive),&#xff0c;location指令的功能是用来匹配不同的url请求&#xff0c;进而对请求做不同的处理和响应&#xff0c;这其中较难理解的是多个location的匹配顺序&#xff0c;本文会作为重点来解释…

Effective Modern C++

模板类型推导 template<typename T> void f(T& parms);//reference template<typename T> void f(const T& parms);//const ref template<typename T> void f(T* parms);//pointer template<typename T> void f(T&& parms);//univers…