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

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.xdnf.cn/news/15172.html

相关文章:

  • 什么是 Bootloader?怎么把它移植到 STM32 上?
  • 《人件》第六章 快乐地工作
  • Python-难点-uinttest
  • 秋招笔试考什么?如何针对性去练习?
  • w459客户管理系统
  • xml映射文件的方式操作mybatis
  • 多线程进阶——JUC的常见类
  • 跨系统开发代码换行符如何解决
  • docker-compose方式搭建lnmp环境——筑梦之路
  • 2025 XYD Summer Camp 7.10 筛法
  • Go语言生态成熟度分析:为何Go还无法像Java那样实现注解式框架?
  • 系统分析师-计算机系统-计算机系统概述存储系统
  • 《Java Web程序设计》实验报告二 学习使用HTML标签、表格、表单
  • 【学习笔记】Linux命令
  • 蓝牙BT UUID的含义以及使用方法案例说明
  • JavaScript加强篇——第七章 浏览器对象与存储要点
  • 《Java Web程序设计》实验报告四 Java Script前端应用和表单验证
  • OpenCL study - code02
  • docker网络与数据持久化
  • 大数据时代UI前端的智能化服务升级:基于用户情境的主动服务设计
  • Elasticsearch 的 `modules` 目录
  • 使用Matlab整车模型进行电动汽车能耗仿真测试方法
  • 【飞算JavaAI】一站式智能开发,驱动Java开发全流程革新
  • 鸿蒙的NDK开发初级入门篇
  • Apache Iceberg数据湖高级特性及性能调优
  • 如何使用postman做接口测试?
  • 《Spring 中上下文传递的那些事儿》Part 8:构建统一上下文框架设计与实现(实战篇)
  • 安全初级作业1
  • Linux中的git命令
  • 【LeetCode 热题 100】24. 两两交换链表中的节点——(解法一)迭代+哨兵