文章目录
- 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,
]
]);
}
}
完结!