使用jwt生成token
一 :首先 composer 安装 firebase/php-jw
github:https://github.com/firebase/php-jwt
composer 命令 : composer require firebase/php-jwt
二:JWT安装完事 建个中间件
php think make:middleware ApiAuth
(ApiAuth 起你 想起的 名字 就OK 叫什么都行。 下面是 我的逻辑 与JWT 验证 还有 app()->user 注入 获取用户信息)
use app\common\library\Auth; use Firebase\JWT\JWT; use think\exception\HttpException; class AdminAuth { public function handle($request, \Closure $next) { // JWT 验证登录 $auth = Auth::instance(); $jwt = substr($request->header('Authorization'), 7); $user = null; try { $jwt = (array)JWT::decode($jwt, env('APP_SECRET'), ['HS256']); if ($jwt && $jwt['exp'] > time()) { $user = $auth->user($jwt); } } catch (\Exception $e) { $jwt = null; } //注入用户 app()->auth = $auth; app()->user = $user; //检查访问权限 if (!$auth->checkPublicUrl()) { if (empty($jwt)) { throw new HttpException(401, '未授权访问'); } if (!$user) { throw new HttpException(401, '登录已过期,请重新登录'); } if ($user['token'] != $jwt['token']) { throw new HttpException(401, '用户验证失败,请重新登录'); } } return $next($request); } }
三:然后在你的控制器模块目录下在建一个middleware.php文件
里面写这样的一句话
这句话的意思就是 这个控制器模块 都需要通过中间件去验证
如果你想忽略哪个控制器方法 那么config配置下 新建 如图
当然 还有你们关心的 Auth::instance();哪里来的 这是封装的方法下面直接代码奉上
放在的位置 app\common\library\Auth;
<?php /** * Created by PhpStorm. * User: Administrator * Date: 2022/3/9 * Time: 15:25 */ namespace app\common\library; use app\api\model\User; use Firebase\JWT\JWT; use think\Db; use think\facade\Request; class Auth { /** * user * @var */ protected $user; protected $config; /** * user_id * @var */ protected $user_id; /** * @var object 对象实例 */ protected static $instance; /** * 类架构函数 * Auth constructor. */ public function __construct() { if ($config = \think\facade\Config::get('auth.')) { $this->config = $config; } } /** * 初始化 * @param array $options * @return object|static */ public static function instance() { if (is_null(self::$instance)) { self::$instance = new static(); } return self::$instance; } /** * 生产token * @param $user_id * @return string */ public function token($user_id) { $time = time(); $JWT_TTL = 7 * 24 * 60 * 60; $token = sha1($user_id . uniqid()); $jwt = [ "user_id" => $user_id, "iat" => $time, "token" => $token, "exp" => $time + $JWT_TTL ]; if (Db::name('user')->where('id', $user_id)->setField('token', $token)) { // $this->clear($user_id); return JWT::encode($jwt, config('config.jwt.jwt_key')); } return ''; } /** * 校验url,是否需要用户验证 * @return bool */ public function checkPublicUrl() { $urls = $this->config; $path = '/' . str_replace('.', '/', strtolower(Request::module() . '/' . Request::controller() . '/' . Request::action())); //判断是否需要验证 foreach ($urls as $val) { foreach ($val as $value) { if ($path == $value) return true; if (strpos($path, $value)) return true; $position = strspn($path, $value); $str = substr($value, $position); if ($str == '*') return true; } } return false; } /** * 当前登录用户 * @param array $jwt * @return array|null|\PDOStatement|string|\think\Model * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ public function user($jwt = []) { if ($jwt) { $user = User::where('id', $jwt['user_id'])->find(); unset($user['password']); $this->user = $user; $this->user_id = $jwt['user_id']; } return $this->user; } /** * 清缓存 * @param $user_id */ public function clear($user_id) { cache('user:info:' . $user_id ? $user_id : $this->user_id, null); } /** * 获取用户id * @return mixed */ public function getUserId() { return $this->user_id; } }
然后在你的登陆接口 返回 JWT的token 不返回 前端拿不到token 怎么调你的接口呢 你说是吧
use 引入 上边封装的 方法
use app\common\library\Auth;
$auth = Auth::instance(); $token = $auth->token($user_info['id']);
转载自https://blog.csdn.net/qq_42678049/article/details/101369511