thinkphp实现后台登录缓存以及页面拦截

张开发
2026/6/2 12:24:29 15 分钟阅读
thinkphp实现后台登录缓存以及页面拦截
用thinkphp实现后台登录缓存主要是运用了JWT扩展生成tokenhttpOnly Cookie登录安全核心用于存放登录token以及JWT凭证并且利用中间件实现全局自动鉴权。1.引入JWT扩展composer require firebase/php-jwt2.配置token密钥在config/app.php界面内配置token密钥jwt [ key a1b2c3d4e5f67890!#$%^*()_ThinkPHP8JwtSecretKey2025, // 自定义密钥越复杂越安全 expire 7200, // Token 过期时间单位秒2小时 alg HS256 // 加密算法 ],注jwt HS256 密钥长度最短长度为 32字节256位3.封装通用token类封装token需要引入JWT扩展内的接口。use Firebase\JWT\JWT; use Firebase\JWT\Key; use Firebase\JWT\ExpiredException;在此次项目内我将封装的通用token类放入了新建的common通用工具目录内。class JwtToken { /** * 生成 Token */ public static function createToken(array $data) { // 从配置文件读取 $key config(app.jwt.key); // 密钥 $expire config(app.jwt.expire); // 过期时间 // 载荷数据官方标准字段 $payload [ iat time(), // 签发时间 exp time() $expire, // 过期时间 data $data // 自定义用户数据 ]; // 生成 Token return JWT::encode($payload, $key, config(app.jwt.alg)); } /** * 验证 Token */ public static function verifyToken(string $token) { try { $key config(app.jwt.key); // 解密 Token $decoded JWT::decode($token, new Key($key, config(app.jwt.alg))); return (array)$decoded-data; } catch (ExpiredException $e) { throw new \Exception(登录已过期); } catch (\Exception $e) { throw new \Exception(登录无效); } } }4.在登录控制器内生成token在登录控制器内引用封装的通用token类随后再在登录方法内调用生成token的方法?php namespace app\controller; use think\Controller; use app\BaseController; use app\common\JwtToken; // 引入封装通用token工具类 class Login extends BaseController { public function doLogin() { /* 其他操作.... */ // 设置token $userData [ account $account, // 最好不要放隐私的数据 ]; $token JwtToken::createToken($userData); // 调用生成token方法 // 写入 httpOnly Cookie核心安全配置 cookie(token, $token, [ expire config(app.jwt.expire), // 设置token过期时间 httponly true, // 开启HttpOnly模式 path /, // Cookie生效路径 ]); return .....; } } ?在这里开启的HttpOnly模式的作用1.前端 JS 永远读不到、改不了这个 Cookie2.只能由浏览器自动携带发送给后端5.退出登录也在登录控制器内此次项目中我是通过前端点击退出按钮并且通过axios向后端发送请求清空httpOnly cookie等待请求完成后在回调函数中提示登录成功并且刷新页面。注需要在route/app.php内配置对应路由Route::post(login/logout, login/logout); // 退出登录thinkphppublic function logout() // 退出登录 { // 清空 httpOnly cookie cookie(token, null, [ expire -1, httponly true, path /, ]); }js$(.header-close).click(function () { axios({ url: /login/logout, method: post }).then(res { alert(退出成功) location.reload(); // 刷新页面 }) })6.全局中间件自动鉴权全站自动验证登录在此次项目我将 JwtCheck.php 放入了新建的 middleware中间件目录内。主要作用是检查是否有token即是否登录如果没有登录则不允许访问除去登录界面在此次项目中我使未登录的人强制跳转至登录界面注在使用中间件时必须先在 app/middleware.php 内注册中间件// 全局自动验证登录 \app\middleware\JwtCheck::class,JwtCheck.php?php namespace app\middleware; use app\common\JwtToken; use think\Request; class JwtCheck { public function handle(Request $request, \Closure $next) { // 获取当前访问的 URI $path strtolower(trim($request-pathinfo(), /)); // 白名单放行登录相关 $allow_paths [ login, // 登录页 http://tp/login login/dologin, // 登录接口 captcha, login/captcha, // 验证码 login/logout // 退出 ]; // 白名单直接放行 if (in_array($path, $allow_paths)) { return $next($request); } // 验证 Token $token cookie(token); if (!$token) { // 如果token为空 return redirect(/login); // 跳转至登录界面 } try { $user JwtToken::verifyToken($token); // 调用验证token方法 $request-user $user; } catch (\Exception $e) { return json([code 0, msg $e-getMessage()]); } return $next($request); } }注在thinkphp中一共有4种类型的中间件1.全局中间件整个项目所有请求、所有模块、所有接口进来必走一遍拦截全站。2.应用模块中间件只针对某个独立模块生效3.路由中间件只给指定路由 / 指定接口单独绑定中间件颗粒度最细。4.控制器中间件写在控制器内部控制当前控制器里的方法全部鉴权 / 排除某些方法本次项目中我所使用的是全局中间件所以我需要在JwtCheck.php内去配置可以在没有token的情况下可以访问的页面。总结以上几个步骤就是我此次在后台创建中实现登录缓存以及页面拦截的方法

更多文章