如何在PHP中使用JWT返回SQL查询结果?
使用JWT返回SQL查询结果的实现方案
首先先修正你现有JWT生成代码里的错误:你调用了不存在的CreateTokenToken函数,应该改成CreateToken;另外Header里的标准字段是typ而非type,同时简化URL安全Base64编码的逻辑。修正后的代码如下:
$secret = "examamplesecrett"; function CreateToken($secret){ // 生成符合标准的JWT Header $header = json_encode([ "typ" => "JWT", "alg" => "HS256" ]); // 生成Payload $payload = json_encode([ 'idUsuarioexample' => '100', 'iat' => time(), 'exp' => time() + 1800, ]); // 封装URL安全Base64编码方法 function base64UrlEncode($data) { return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); } $headerBase64 = base64UrlEncode($header); $payloadBase64 = base64UrlEncode($payload); // 生成签名 $signature = hash_hmac('sha256', $headerBase64 . '.' . $payloadBase64, $secret, true); $signatureBase64 = base64UrlEncode($signature); $jwt = $headerBase64 . "." . $payloadBase64 . "." . $signatureBase64; return $jwt; } $token = CreateToken($secret); echo $token ;
接下来实现完整流程:验证JWT合法性后返回SQL查询结果,步骤如下:
1. 编写JWT验证函数
负责解析Token、验证签名和过期时间:
function validateJWT($jwt, $secret) { $parts = explode('.', $jwt); if(count($parts) !== 3) return false; list($headerBase64, $payloadBase64, $signatureBase64) = $parts; // 解码Header和Payload $header = json_decode(base64_decode(strtr($headerBase64, '-_', '+/')), true); $payload = json_decode(base64_decode(strtr($payloadBase64, '-_', '+/')), true); // 验证签名是否匹配 $expectedSignature = rtrim(strtr(base64_encode(hash_hmac('sha256', $headerBase64 . '.' . $payloadBase64, $secret, true)), '+/', '-_'), '='); if($signatureBase64 !== $expectedSignature) return false; // 验证Token是否过期 if(isset($payload['exp']) && $payload['exp'] < time()) return false; return $payload; }
2. 连接数据库执行查询
以MySQL为例,用PDO实现安全的数据库查询:
function getSQLData($userId) { $dbHost = 'localhost'; $dbName = '你的数据库名'; $dbUser = '数据库用户名'; $dbPass = '数据库密码'; try { $pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 根据Payload中的用户ID查询数据 $stmt = $pdo->prepare("SELECT * FROM 你的表名 WHERE id_usuario = ?"); $stmt->execute([$userId]); return $stmt->fetchAll(PDO::FETCH_ASSOC); } catch(PDOException $e) { return ['error' => $e->getMessage()]; } }
3. 整合完整流程
处理前端请求,验证Token后返回查询结果:
// 从请求头获取Bearer Token $authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; if(strpos($authHeader, 'Bearer ') === 0) { $jwt = substr($authHeader, 7); $payload = validateJWT($jwt, $secret); if($payload) { // 从Payload提取用户ID,执行查询 $userId = $payload['idUsuarioexample']; $data = getSQLData($userId); // 返回JSON格式结果 header('Content-Type: application/json'); echo json_encode($data); exit; } } // Token验证失败时返回未授权错误 header('HTTP/1.1 401 Unauthorized'); echo json_encode(['error' => '无效或过期的Token']);
注意事项
- JWT的Payload不适合存储大量数据,不要把SQL查询结果直接塞进Payload,应验证Token后单独返回数据。
- 务必使用HTTPS传输JWT,防止Token被网络窃取。
- 数据库连接信息不要硬编码,建议放在权限受控的配置文件中。
内容的提问来源于stack exchange,提问作者Carlos Alejandro
相关产品推荐
相关产品推荐

