当前位置: 首页 > 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.lryc.cn/news/585894.html

相关文章:

  • 深入解析 LinkedList
  • 在 Android 库模块(AAR)中,BuildConfig 默认不会自动生成 VERSION_CODE 和 VERSION_NAME 字段
  • 手机识别数据集,2628张原始图片,支持yolo,coco json,pasical voc xml等格式的标注
  • 搭建云手机教程
  • 深大计算机游戏开发实验三
  • Apache HTTP Server 从安装到配置
  • 实习内容总结
  • javaEE——synchronized关键字
  • docker 443错误 lookup docker.mirrors.ustc.edu.cn: no such host
  • Vue Vue-route (5)
  • 【C#】GraphicsPath的用法
  • Vscode中使用C++代码进行debug
  • 阿里云服务器安装JDK21
  • WildCard野卡已跑路(包含gpt plus升级方案)
  • 2025.7.12总结
  • Python-类-面向对象-继承-多继承-学习笔记
  • RISC-V:开源芯浪潮下的技术突围与职业新赛道 (四) 产业应用全景扫描
  • CSS选择器进行定位
  • 开源 python 应用 开发(五)python opencv之目标检测
  • Android音视频探索之旅 | C++层使用OpenGL ES实现音频渲染
  • 10. 垃圾回收的算法
  • 【字符串移位包含问题】2022-8-7
  • 【飞算JavaAI】一站式智能开发,驱动Java开发全流程革新
  • 缺陷特征粘贴增强流程
  • 13. G1垃圾回收器
  • git版本发布
  • Kotlin基础学习记录
  • 基于定制开发开源AI智能名片S2B2C商城小程序的社群游戏定制策略研究
  • 云计算三大服务模式深度解析:IaaS、PaaS、SaaS
  • AI:机器人行业发展现状