博主PHP环境为PHP8.2,所以官方默认下载4.0版本,
1、首先安装JWT扩展包:这里安装的4.0的,其他版本请查看JWT官网:https://jwt.io/libraries
composer require lcobucci/jwt
2、封装类:JwtUtil.php
在项目http目录下创建JwtAuth目录,并创建JwtUtil.php文件
<?php namespace App\Http\JwtAuth; use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Signer\Hmac\Sha256; use Lcobucci\JWT\Signer\Key\InMemory; /** * 单例模式 * Class JwtUtil * @package App\JwtAuth\JwtUtil */ class JwtUtil { private $config; private $key = "Ge1KCTRhdVsmUUZY0GrwgEvLubPvLOCM"; private $iss = "tpxhm.com";//颁发者(iss声明) private $aud = "tpxhmauth.com";//访问群体(aud声明) private $jti = "5t6y9400453"; //id(jti声明) private $expTime = 1;//令牌有效时间,单位小时 private static $instance;// 单例模式JwtAuth句柄 // 获取JwtAuth的句柄 public static function getInstance() { if (is_null(self::$instance)) { self::$instance = new self(); } return self::$instance; } /** * 构造 */ public function __construct() { self::init(); } /** * 初始化 */ private function init() { $config = Configuration::forSymmetricSigner( new Sha256(), InMemory::base64Encoded($this->key) ); $this->config = $config; } /** * 创建JWT * @param array $arrClaim * @return string * @throws \Exception * @author 简忆博客 */ public function createToken(array $arrClaim) { $config = $this->config; assert($config instanceof Configuration); if (is_array($arrClaim) && count(array_filter(array_keys($arrClaim),'is_string'))>0) { //是关联数组 } else { //不是关联数组 throw new \Exception("claim参数必须为关联数组"); } $now = new \DateTimeImmutable(); $token = $config->builder() // 配置颁发者(iss声明) ->issuedBy($this->iss) // 配置访问群体(aud声明) ->permittedFor($this->aud) // 配置id(jti声明) ->identifiedBy($this->jti) // 配置令牌发出的时间(iat声明) ->issuedAt($now) // 配置令牌的过期时间(exp claim) ->expiresAt($now->modify("+{$this->expTime} hour")); //claim foreach ($arrClaim as $k => $item) { $token = $token->withClaim($k, $item); } // 生成新令牌 $token = $token->getToken($config->signer(), $config->signingKey()); return $token->toString(); } /** * 解析token * @param string $jwt * @return mixed * @author 简忆博客 */ public function parseToken(string $jwt) { $config = $this->config; $token = $config->parser()->parse($jwt); return $token->claims(); } /** * 验证令牌 * @param $jwt * @return mixed * @throws \Exception * @author 简忆博客 */ public function validatorToken($jwt) { $config = $this->config; $token = $config->parser()->parse($jwt); $claims = $token->claims(); $jti = (string)$claims->get('jti'); $iss = (string)$claims->get('iss'); $aud = $claims->get('aud'); $exp = $claims->get('exp'); $now = new \DateTimeImmutable(); // 是否过期 if ($exp < $now) { throw new \Exception("身份已过期"); } //验证jwt id是否匹配 $validate_jwt_id = new \Lcobucci\JWT\Validation\Constraint\IdentifiedBy($jti); // 验证签发人url是否正确 $validate_issued = new \Lcobucci\JWT\Validation\Constraint\IssuedBy($iss); // 验证客户端url是否匹配 $validate_aud = new \Lcobucci\JWT\Validation\Constraint\PermittedFor($aud[0]); $config->setValidationConstraints($validate_jwt_id, $validate_issued, $validate_aud); $constraints = $config->validationConstraints(); //验证 if (!$config->validator()->validate($token, ...$constraints)) { throw new \Exception("非法的请求"); } return $claims; } }
3、创建middleware中间件
<?php namespace App\Http\Middleware; use App\Http\JwtAuth\JwtUtil; use App\Http\Response\ApiErrDesc; use App\Http\Response\ResponseJson; use Closure; use Illuminate\Http\Request; class CheckLogins { use ResponseJson; /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle(Request $request, Closure $next) { $token =!empty($_SERVER['HTTP_TOKEN']) ? $_SERVER['HTTP_TOKEN'] : ''; if ($token) { //检验token $jwtAuth = JwtUtil::getInstance(); $jwtAuth = $jwtAuth->validatorToken($token); if($jwtAuth){ return $next($request); }else { return $this->jsonData(ApiErrDesc::EXPIRES_TIME[0], ApiErrDesc::EXPIRES_TIME[1]); } } else { return $this->jsonData(ApiErrDesc::LOGIN_TOKEN[0], ApiErrDesc::LOGIN_TOKEN[1]); } } }
4、创建登录控制器:LoginController.php
<?php namespace App\Http\Controllers\Admin; use App\Http\JwtAuth\JwtUtil; use App\Http\Response\ApiErrDesc; use App\Http\Controllers\Controller; use App\Http\Requests\Api\CheckCaptcha; use App\Http\Response\ResponseJson; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class LoginController extends Controller { use ResponseJson; /* * 用户登录 * * @param Request $request * @return false|string * */ public function login(Request $request){ //获取客户端传递的参数 $name = $request->input('username'); $password = $request->input('password'); try { //去数据库中查询改用户信息 $res=DB::table('sys_admin')->where(array('name'=>$name,'stop'=>0))->first(); if(!$res){ return $this->jsonData(ApiErrDesc::NO_USER[0],ApiErrDesc::NO_USER[1]); } }catch (\Illuminate\Database\QueryException $exception){ return $this->jsonData(ApiErrDesc::ERROR[0],$exception->getMessage()); } //password_hash() $userPasswordHash = $res->password; if(!password_verify($password,$userPasswordHash)){ return $this->jsonData(ApiErrDesc::ERR_PASSWORD[0],ApiErrDesc::ERR_PASSWORD[1]); } //验证成功,生成jwt返回 $token = JwtUtil::getInstance()->createToken(['uid' => $res->id]); //登录成功 return $this->jsonData(ApiErrDesc::LOGIN_SUCCESS[0],ApiErrDesc::LOGIN_SUCCESS[1],$token); } } 5、查询用户信息 <?php namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use App\Http\JwtAuth\JwtAuth; use App\Http\JwtAuth\JwtUtil; use App\Http\Response\ApiErrDesc; use App\Http\Response\ResponseJson; class PictureController extends Controller { use ResponseJson; public function info(){ //检验token $token =!empty($_SERVER['HTTP_TOKEN']) ? $_SERVER['HTTP_TOKEN'] : ''; if (!$token){ return $this->jsonData(ApiErrDesc::LOGIN_TOKEN[0], ApiErrDesc::LOGIN_TOKEN[1]); } $jwtAuth = JwtUtil::getInstance(); $claims = $jwtAuth->validatorToken($token); //得到用户id $uid = $claims->get('uid'); $user = DB::table('sys_admin')->where('id',$uid)->first(); if(!$user){ return $this->jsonData(ApiErrDesc::NO_USER[0],ApiErrDesc::NO_USER[1]); } } }
一个简单的案例供大家参考,laravel8的请参考这边文章:Laravel8使用jwt+redis+mysql 实现登录功能
文章评论(0)