thinkphp6中jwt的使用
-
安装JWT插件
composer require firebase/php-jwt
-
创建User模型
php think make:model User
-
创建User控制器
php think make:controller User
-
封装创建token函数,要在User模型中创建
// 加密的秘钥 protected $key = "test"; // 过期时间 protected $exptime = 60*60*24; // 一天 function createToken($user) { // jwt的签发秘钥 $key = md5($this->key); // 签发时间 $time = time(); // 过期时间 $expire = $time + $this->exptime; $token = [ "user" => $user, "iat" => $time, "nbf" => $time, "exp" => $expire ]; $jwt = JWT::encode($token,$key,'HS256'); return $jwt; }
-
封装验证token函数,要在User模型中创建
// 加密的秘钥 protected $key = "test"; // 过期时间 protected $exptime = 60*60*24; // 一天 function verifyToken($token) { $key = md5($this->key); $headers = ['HS256']; try { $jwtAuth = json_encode(JWT::decode($token, $key, $headers)); if ($jwtAuth->exp < time()) { throw new ExpiredException(); } return [ "code" => 1, "msg" => "通过", "data" => $jwtAuth[0] ]; }catch (ExpiredException $e) { return [ "code" => 0, "msg" => "token已过期" ]; } catch (\Exception $e) { return [ "code" => 0, "msg" => "token无效" ]; } }
-
在User控制器中使用
<?php declare (strict_types = 1); namespace app\controller; use app\BaseController; use app\middleware\Auth; use think\Db; use think\Request; class Users extends BaseController { protected $nologin = ["login"]; /** * 显示资源列表 * * @return \think\Response */ public function index() { // } public function login() { // 登录成功 // 模拟用户信息 $user = [ "id" => 1, "username" => "text" ]; return json([ "msg" => "登录成功", "data" => (new \app\model\Users())->createToken($user) ]); } /** * 保存新建的资源 * * @param \think\Request $request * @return \think\Response */ public function save(Request $request) { // } /** * 显示指定的资源 * * @param int $id * @return \think\Response */ public function read($id) { // } /** * 保存更新的资源 * * @param \think\Request $request * @param int $id * @return \think\Response */ public function update(Request $request, $id) { // } /** * 删除指定资源 * * @param int $id * @return \think\Response */ public function delete($id) { // } }
-
创建中间件来进行校验token
- 创建中间件
php think make:middleware Auth
- 编写校验代码
<?php declare (strict_types = 1); namespace app\middleware; class Auth { /** * 处理请求 * * @param \think\Request $request * @param \Closure $next * @return Response */ public function handle($request, \Closure $next) { $token = $request->header('token',''); if(empty($token)){ return json([ "code" => 0, "msg" => "token不能为空" ]); } $res = (new \app\model\Users())->verifyToken($token); if($res['code'] == 0){ return json([ "code" => 0, "msg" => $res['msg'] ]); }else{ $request->user = $res['data']; return $next($request); } } }
-
在基础控制器中使用中间件
BaseController.php
<?php declare (strict_types = 1); namespace app; use app\middleware\Auth; use think\App; use think\exception\ValidateException; use think\Validate; /** * 控制器基础类 */ abstract class BaseController { /** * Request实例 * @var \think\Request */ protected $request; /** * 应用实例 * @var \think\App */ protected $app; /** * * 是否批量验证 * @var bool */ protected $batchValidate = false; /** * 控制器中间件 * @var array */ protected $middleware = []; /** * 配置控制器不需要检验token的方法 * @var array */ protected $nologin = []; /** * 构造方法 * @access public * @param App $app 应用对象 */ public function __construct(App $app) { $this->app = $app; $this->request = $this->app->request; // 配置中间件 $this->middleware = [ Auth::class => ['except' => $this->nologin] ]; // 控制器初始化 $this->initialize(); } // 初始化 protected function initialize() {} /** * 验证数据 * @access protected * @param array $data 数据 * @param string|array $validate 验证器名或者验证规则数组 * @param array $message 提示信息 * @param bool $batch 是否批量验证 * @return array|string|true * @throws ValidateException */ protected function validate(array $data, $validate, array $message = [], bool $batch = false) { if (is_array($validate)) { $v = new Validate(); $v->rule($validate); } else { if (strpos($validate, '.')) { // 支持场景 [$validate, $scene] = explode('.', $validate); } $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate); $v = new $class(); if (!empty($scene)) { $v->scene($scene); } } $v->message($message); // 是否批量验证 if ($batch || $this->batchValidate) { $v->batch(true); } return $v->failException(true)->check($data); } }
-
在控制器中使用
<?php declare (strict_types = 1); namespace app\controller; use app\BaseController; use think\Request; // 继承基础控制器 class Users extends BaseController { // 配置登录接口不用校验token protected $nologin = ["login"]; /** * 显示资源列表 * * @return \think\Response */ public function index() { echo 22; } public function login() { // 登录成功 // 模拟用户信息 $user = [ "id" => 1, "username" => "text" ]; return json([ "msg" => "登录成功", "data" => (new \app\model\Users())->createToken($user) ]); } /** * 保存新建的资源 * * @param \think\Request $request * @return \think\Response */ public function save(Request $request) { // } /** * 显示指定的资源 * * @param int $id * @return \think\Response */ public function read($id) { // } /** * 保存更新的资源 * * @param \think\Request $request * @param int $id * @return \think\Response */ public function update(Request $request, $id) { // } /** * 删除指定资源 * * @param int $id * @return \think\Response */ public function delete($id) { // } }