Installation and use of thinkphp5.1-jwt
Install the jwt plug-in
Add it to the require in composer.json Configure as follows
"firebase/php-jwt": "^5.0"
Execute composer update in the project root directory.
Create An auth middleware
php think make:middleware Auth
Open applicationhttpmiddlewareAuth file
<?php namespace app\http\middleware; use Firebase\JWT\JWT; use Firebase\JWT\SignatureInvalid\Exception; use think\exception\TokenException; use think\exception\ValidateException; use think acade\Cache; use think acade\Config; class Auth { public function handle($request, Closure $next) { $bearer_token = []; $bearer = $request->header('authorization');//取header中的token if ($bearer !== null) { //不空尝试去匹配 preg_match('/bearers*(S+)/i', $bearer, $bearer_token); } if (empty($bearer_token[1])) { //匹配不到结果尝试去url中获取 if ($request->param('token') !== null) { $token = $request->param('token'); }else{ throw new TokenException('请登录', 401); } }else{ $token=$bearer_token[1]; } try { $de_token = JWT::decode($token, Config::get('JWT_KEY'), Config::get('JWT_ENCRYPTION')); } catch (SignatureInvalidException $exception) { //捕获JWT解析错误 throw new TokenException('无效令牌', 401); } catch (Exception $exception) { throw new TokenException('请重新登录', 401); } if ($de_token->voe < time() && $de_token->exp > time()) { throw new TokenException('请换取新令牌', 402); } else if ($de_token->voe < time()) { throw new TokenException('请重新登录', 401); } if (Cache::tag('login')->get('token_' . $de_token->data->uid) != $token) { throw new TokenException('用户信息错误,请重新登录', 401); } if ($de_token->data->is_ban == 1) { throw new ValidateException('该账户已被封禁'); } $request->auth = $de_token->data->uid; return $next($request); } }
Create a controller Loginphp think make:controller login/Login --plain
The code is as follows
<?php namespace app\login\controller; use app\common\help; use app\common\service\OperationToken; use think\Controller; use think\Db; use think\Request; class Login extends Controller { public function login(Request $request) { $info = Db::name('user')->field('id,uuid,nick,gender,icon,im_accid,im_icon,is_ban')->where('del_time', '=', '0')->where(['mobile' => $request->param('phone'), 'password' => md5($request->param('password'))])->findOrEmpty(); if ($info == null || empty($info)) { return help::errJsonReturn('账号或密码错误'); } $token = OperationToken::crearToken($info['id'], $info['uuid'], $info['is_ban']); return json([ 'type' => 'Bearer ', 'access_token'=>$token['token'], 'exp_time'=>$token['exp'], 'voe_time'=>$token['voe'], 'iat_time'=>time() ]); } }
Create a new common folder under application, create a new service folder under common, and create it under the service folder
OperationToken.php
<?php namespace app\common\service; use think\Db; use think acade\Cache; use Firebase\JWT\JWT; use think acade\Config; class OperationToken { public static function crearToken(int $uid, string $uuid, int $is_ban): array { $time = time(); $info_token = [ 'iat' => $time,//签发时间 'voe' => Config::get('TOKEN_VOE',7200) + $time,//换取有效时间 'exp' => Config::get('TOKEN_EXP',3600)+$time,//有效时间 'sign' => base64_encode($uuid),//签名 'data' => [ 'uid' => $uid,//用户id 'is_ban' => $is_ban,//是否被禁用 ] ]; $token = JWT::encode($info_token, Config::get('JWT_KEY')); Cache::tag('login')->set('token_' . $uid, $token, Config::get('TOKEN_VOE',7200) + $time); Db::name('user_login_log')->insert( [ 'uid'=>$uid, 'token'=>$token, 'iat_time'=>$time, 'ip'=>ip2long(request()->ip()), 'exp_time'=>Config::get('TOKEN_EXP',3600)+$time, 'voe_time'=> Config::get('TOKEN_VOE',7200) + $time ] ); return [ 'token'=>$token, 'voe' =>Config::get('TOKEN_VOE',7200) + $time, 'exp' => Config::get('TOKEN_EXP',3600)+$time]; } }
Append parameters at the end of the config/app.php document and take over error control
// 异常处理handle类 留空使用 think\exception\Handle 'exception_handle' => function ($e) { //参数验证错误 if ($e instanceof think\exception\ValidateException) { return json(['msg' => $e->getError()], 422); } //route未定义 if ($e instanceof think\exception\ValidateException) { return json(['msg' => $e->getMessage()], 404); } //token过期/无效 401-令牌/账号密码错误 402-令牌过期可旧换新 403-无权限访问 if ($e instanceof hinkexceptionTokenException) { return json(['msg' => $e->getError()], $e->getCode()); } // 请求异常 if ($e instanceof HttpException && request()->isAjax()) { return response(['msg' => $e->getMessage()], $e->getStatusCode()); } },
thinkphp5.1-jwt Installation, use and routing parameter verification
Create a new TokenException.php under thinkphplibrary hinkexception
The code is as follows
<?php namespace think\exception; class TokenException extends HttpException { protected $error; public function __construct($error, $code = 0) { $this->error = $error; $this->message = $error; $this->code = $code; } /** * 获取验证错误信息 * @access public * @return array|string */ public function getError() { return $this->error; } }
Create a login validator
php think make:validate login/Login
The code is as follows
<?php namespace app\login validate;use think\Validate;class Login extends Validate { /** * 定义验证规则 * 格式:'字段名' => ['规则1','规则2'...] * * @var array */ protected $rule = [ 'phone'=>'require|mobile', 'password'=>'require|length:4,12' ]; /** * 定义错误信息 * 格式:'字段名.规则名' => '错误信息' * * @var array */ protected $message = [ 'phone.mobile'=>'phone格式错误', 'password.length'=>'密码长度错误' ]; protected $scene=[ 'login'=>['phone','password'] ]; }
Open route/route.php
The code is as follows
<?php use think acade\Route; Route::get('/','index/Index/index'); Route::group('account',function (){ Route::post('/login','login/Login/login')->validate('applogin alidateLogin','login'); }); //需要验证登录 Route::group('api',function (){ Route::post('/user','index/Index/index'); })->middleware(apphttpmiddlewareAuth::class);
The middleware here can be registered in middleware.php according to the official documentation, but a problem was found during the test. The route does not execute the middleware method. When accessed, all middleware registered in middleware.php will be executed sequentially from top to bottom, so it is rewritten. For middleware(apphttpmiddlewareAuth::class); use middleware to create a new help.php under common
The code is as follows
<?php namespace appcommon; class help { public static function susJsonReturn(array $data=[],string $msg='请求成功',int $code=1) { return json([ 'msg'=>$msg, 'data'=>$data, 'code'=>$code ]); } public static function errJsonReturn(string $msg = '请求失败', int $code = 0, array $data = []) { return json([ 'msg'=>$msg, 'data'=>$data, 'code'=>$code ]); } }
Create a new database in the database and create two new tables
CREATE TABLE `xn_user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `uuid` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'uuid', `password` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '登录密码', `name` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '真实姓名', `nick` varchar(8) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '昵称', `gender` enum('1','2','0') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '用户性别,0 表示未知,1 表示男,2 女表示女', `regist_time` int(11) unsigned DEFAULT NULL, `icon` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '头像', `mobile` char(11) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '手机号', `im_accid` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'im账号', `im_icon` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'im头像', `im_email` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'im邮箱', `im_birth` varchar(16) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'im生日', `im_mobile` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'im手机号码', `create_time` int(11) unsigned DEFAULT '0', `del_time` int(11) unsigned DEFAULT '0', `is_ban` enum('0','1') COLLATE utf8mb4_unicode_ci DEFAULT '0' COMMENT '是否封号', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE `xn_user_login_log` ( `uid` int(11) NOT NULL DEFAULT '0' COMMENT '用户id', `token` text COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '登录时的令牌', `iat_time` int(11) DEFAULT '0' COMMENT '登录时间', `ip` bigint(20) unsigned DEFAULT '0' COMMENT '登录ip-ip2long', `exp_time` int(11) DEFAULT '0' COMMENT '失效时间', `voe_time` int(11) DEFAULT '0' COMMENT 'token旧换新有效时间', KEY `login_log_uid` (`uid`,`ip`,`token`(32)) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Recommended tutorial: "TP5"
The above is the detailed content of thinkPHP configuration jwt (code example). For more information, please follow other related articles on the PHP Chinese website!