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

tp8.0\jwt接口安全验证

环境:php8.3\tp8.1\firebase-jwt6.1

app\middleware\JwtAuth

<?php
namespace app\middleware;use app\common\library\JwtHandler;
use think\Request;
use think\facade\Env;class JwtAuth
{public function handle(Request $request, \Closure $next){// 获取当前请求路径$path = $request->pathinfo();// 如果是登录或注册接口,跳过 Token 校验if (in_array($path, ['api/auth/login/', 'api/auth/register/'])) {return $next($request);}// 获取 Authorization 头$token = $request->header('Authorization');if (!$token) {$this->handleTokenError('Token not provided');}// 如果 Authorization 头中有 Bearer token,处理它if (str_starts_with($token, 'Bearer ')) {$token = substr($token, 7);  // 去掉 'Bearer ' 前缀}try {// 解码并验证 Token$data = JwtHandler::getData($token);if (!$data) {$this->handleTokenError('Invalid or expired token');}// 将解码的用户数据附加到请求对象$request->user = $data;} catch (\Exception $e) {$this->handleTokenError('Invalid or expired token');}return $next($request);}// 处理 Token 错误的公共方法private function handleTokenError($message): void{// 在生产环境中提供简洁的错误信息if (Env::get('app.env') === 'production') {json(['code' => 401,'message' => 'Invalid or expired token']);return;}// 在开发环境中提供详细的错误信息json(['code' => 401,'message' => $message]);}
}

app\common\library\JwtHandler;

<?phpnamespace app\common\library;use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use think\exception\ValidateException;class JwtHandler
{private static string $key = 'quwei';  // 密钥/*** 生成JWT* @param array $payload* @return string* @throws ValidateException*/public static function encode(array $payload): string{$issuedAt = time(); // 当前时间$expirationTime = $issuedAt + 60;  // 设置过期时间为1小时$payload['iat'] = $issuedAt;  // 签发时间$payload['exp'] = $expirationTime; // 过期时间try {// 生成JWTreturn JWT::encode($payload, self::$key, 'HS256');} catch (\UnexpectedValueException $e) {throw new ValidateException('Error encoding JWT: ' . $e->getMessage());}}/*** 解码JWT* @param string $jwt* @return object|null* @throws ValidateException*/public static function decode(string $jwt): ?object{try {// 解码JWTreturn JWT::decode($jwt, new Key(self::$key, 'HS256'));} catch (\Firebase\JWT\ExpiredException $e) {throw new ValidateException('Token expired: ' . $e->getMessage());} catch (\UnexpectedValueException $e) {throw new ValidateException('Invalid token: ' . $e->getMessage());} catch (\Exception $e) {throw new ValidateException('Error decoding JWT: ' . $e->getMessage());}}/*** 获取JWT中的数据* @param string $jwt* @return array|null*/public static function getData(string $jwt): ?array{try {$decoded = self::decode($jwt);return $decoded ? (array)$decoded : null;} catch (ValidateException $e) {return null; // 解码失败时返回 null}}
}

app\api\controller\auth.php

<?phpnamespace app\api\controller;use app\BaseController;
use app\common\library\JwtHandler;
use think\Request;
use think\response\Json;class Auth extends BaseController
{/*** 用户登录,生成JWT* @param Request $request* @return Json*/public function login(Request $request): Json{$username = $request->post('username');$password = $request->post('password');// 假设你通过用户名和密码来验证用户if ($username === 'John' && $password === '123') {// 生成 JWT,payload 可以根据需要调整$payload = ['sub' => 1, // 用户ID'name' => $username,'role' => 'admin'];// 生成JWT$jwt = JwtHandler::encode($payload);return json(['code' => 200, 'message' => 'Login successful', 'token' => $jwt]);}return json(['code' => 400, 'message' => 'Invalid credentials'], 400);}/*** 验证JWT,获取用户信息* @param Request $request* @return Json*/public function me(Request $request): Json{$token = $request->header('Authorization');  // 获取Authorization头中的Tokenif (!$token) {return json(['code' => 401, 'message' => 'Token not provided'], 401);}// 解码Tokentry {$data = JwtHandler::getData($token);if ($data) {return json(['code' => 200, 'message' => 'Success', 'data' => $data]);}return json(['code' => 401, 'message' => 'Invalid or expired token'], 401);} catch (\Exception $e) {return json(['code' => 401, 'message' => 'Invalid or expired token'], 401);}}public function getUserProfile(Request $request): Json{// 直接访问解码后的用户信息$user = $request->user;// 返回当前用户的个人资料return json(['code' => 200, 'data' => $user]);}
}

这是完整的步骤,欢迎大家指正。

http://www.dtcms.com/a/275377.html

相关文章:

  • Ubuntu快速搭建QT开发环境指南,5000字解析!!
  • 自动化证书续签工具针对VPS服务器HTTPS服务的维护实践
  • windows电脑远程win系统服务器上的wsl2
  • 企业选择大带宽服务器租用的原因有哪些?
  • 北京企业纷纷“借兵”:揭秘软件人力外包走俏的四大真相
  • 9. JVM垃圾回收
  • 持有对象-基本概念
  • 多 Agent 强化学习实践指南(一):CTDE PPO 在合作捕食者-猎物游戏中的应用详解
  • 检查输入有效性(指针是否为NULL)和检查字符串长度是否为0
  • 图像扭曲增强处理流程
  • 基于 AI 的大前端网络请求优化:动态调整与缓存策略
  • Nginx模块注册全流程揭秘:为什么Nginx模块化架构依然是Web服务器的“金标准”?
  • stack和queue的使用和模拟实现以及了解deque
  • 以数据为核心,以业务为导向,漫谈数据可视化应用
  • 网络编程员工管理系统
  • 【MogDB】一种基于ctid分片并发查询以提升大表查询性能的方式
  • RBAC权限模型深度解析:从理论到企业级实践
  • 贪心算法题解——跳跃游戏 II【LeetCode】
  • The Black Heart
  • 飞算 JavaAI 智能编程助手:颠覆编程旧模式,重构新生态
  • 【极客日常】后端任务动态注入执行策略的一种技术实现
  • 27.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--币种服务(一)
  • .net机器学习框架:ML.NET数据处理
  • 【嵌入式硬件实例】-555定时器实现倍压电路
  • 钉钉小程序开发环境配置与前端开发指南
  • 计算机毕业设计ssm基于SSM的萌宠交流平台 基于SSM的毛孩子互动分享与领养系统 SSM架构下的宠物社交·商城·救助一体化平台
  • Mac M芯片安装RocketMQ服务
  • 【Docker基础】Dockerfile指令速览:基础常用指令详解
  • 【STM32实践篇】:最小系统组成
  • 实战指南:用pmap+gdb排查Linux进程内存问题