Home > PHP Framework > ThinkPHP > body text

thinkPHP configuration jwt (code example)

L
Release: 2020-05-27 13:48:39
forward
6236 people have browsed it

thinkPHP configuration jwt (code example)

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(&#39;authorization&#39;);//取header中的token
 if ($bearer !== null) {
 //不空尝试去匹配
 preg_match(&#39;/bearers*(S+)/i&#39;, $bearer, $bearer_token);
 }
 if (empty($bearer_token[1])) {
 //匹配不到结果尝试去url中获取
 if ($request->param(&#39;token&#39;) !== null) {
 $token = $request->param(&#39;token&#39;);
 }else{
 throw new TokenException(&#39;请登录&#39;, 401);
 }
 }else{
 $token=$bearer_token[1];
 }
 try {
 $de_token = JWT::decode($token, Config::get(&#39;JWT_KEY&#39;), Config::get(&#39;JWT_ENCRYPTION&#39;));
 } catch (SignatureInvalidException $exception) {
 //捕获JWT解析错误
 throw new TokenException(&#39;无效令牌&#39;, 401);
 } catch (Exception $exception) {
 throw new TokenException(&#39;请重新登录&#39;, 401);
 }
 if ($de_token->voe < time() && $de_token->exp > time()) {
 throw new TokenException(&#39;请换取新令牌&#39;, 402);
 } else if ($de_token->voe < time()) {
 throw new TokenException(&#39;请重新登录&#39;, 401);
 }
 if (Cache::tag(&#39;login&#39;)->get(&#39;token_&#39; . $de_token->data->uid) != $token) {
 throw new TokenException(&#39;用户信息错误,请重新登录&#39;, 401);
 }
 if ($de_token->data->is_ban == 1) {
 throw new ValidateException(&#39;该账户已被封禁&#39;);
 }
 $request->auth = $de_token->data->uid;
 return $next($request);
 }
}
Copy after login

Create a controller Login
php 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(&#39;user&#39;)->field(&#39;id,uuid,nick,gender,icon,im_accid,im_icon,is_ban&#39;)->where(&#39;del_time&#39;, &#39;=&#39;, &#39;0&#39;)->where([&#39;mobile&#39; => $request->param(&#39;phone&#39;), &#39;password&#39; => md5($request->param(&#39;password&#39;))])->findOrEmpty();
 if ($info == null || empty($info)) {
 return help::errJsonReturn(&#39;账号或密码错误&#39;);
 }
 $token = OperationToken::crearToken($info[&#39;id&#39;], $info[&#39;uuid&#39;], $info[&#39;is_ban&#39;]);
 return json([
 &#39;type&#39; => &#39;Bearer &#39;,
 &#39;access_token&#39;=>$token[&#39;token&#39;],
 &#39;exp_time&#39;=>$token[&#39;exp&#39;],
 &#39;voe_time&#39;=>$token[&#39;voe&#39;],
 &#39;iat_time&#39;=>time()
 ]);
 }
}
Copy after login

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 = [
 &#39;iat&#39; => $time,//签发时间
 &#39;voe&#39; => Config::get(&#39;TOKEN_VOE&#39;,7200) + $time,//换取有效时间
 &#39;exp&#39; => Config::get(&#39;TOKEN_EXP&#39;,3600)+$time,//有效时间
 &#39;sign&#39; => base64_encode($uuid),//签名
 &#39;data&#39; => [
 &#39;uid&#39; => $uid,//用户id
 &#39;is_ban&#39; => $is_ban,//是否被禁用
 ]
 ];
 $token = JWT::encode($info_token, Config::get(&#39;JWT_KEY&#39;));
 Cache::tag(&#39;login&#39;)->set(&#39;token_&#39; . $uid, $token, Config::get(&#39;TOKEN_VOE&#39;,7200) + $time);
 Db::name(&#39;user_login_log&#39;)->insert(
 [
 &#39;uid&#39;=>$uid,
 &#39;token&#39;=>$token,
 &#39;iat_time&#39;=>$time,
 &#39;ip&#39;=>ip2long(request()->ip()),
 &#39;exp_time&#39;=>Config::get(&#39;TOKEN_EXP&#39;,3600)+$time,
 &#39;voe_time&#39;=> Config::get(&#39;TOKEN_VOE&#39;,7200) + $time
 ]
 );
 return [
 &#39;token&#39;=>$token, 
 &#39;voe&#39; =>Config::get(&#39;TOKEN_VOE&#39;,7200) + $time,
 &#39;exp&#39; => Config::get(&#39;TOKEN_EXP&#39;,3600)+$time];
 }
}
Copy after login

Append parameters at the end of the config/app.php document and take over error control

// 异常处理handle类 留空使用 think\exception\Handle
&#39;exception_handle&#39; => function ($e) {
 //参数验证错误
 if ($e instanceof think\exception\ValidateException) {
 return json([&#39;msg&#39; => $e->getError()], 422);
 }
 //route未定义
 if ($e instanceof think\exception\ValidateException) {
 return json([&#39;msg&#39; => $e->getMessage()], 404);
 } //token过期/无效 401-令牌/账号密码错误 402-令牌过期可旧换新 403-无权限访问
 if ($e instanceof hinkexceptionTokenException) {
 return json([&#39;msg&#39; => $e->getError()], $e->getCode());
 } // 请求异常
 if ($e instanceof HttpException && request()->isAjax()) {
 return response([&#39;msg&#39; => $e->getMessage()], $e->getStatusCode()); 
} 
},
Copy after login

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;
 }
}
Copy after login

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
{ /**
 * 定义验证规则
 * 格式:&#39;字段名&#39; => [&#39;规则1&#39;,&#39;规则2&#39;...]
 *
 * @var array */
 protected $rule = [ &#39;phone&#39;=>&#39;require|mobile&#39;,
 &#39;password&#39;=>&#39;require|length:4,12&#39;
 ]; 
 /**
 * 定义错误信息
 * 格式:&#39;字段名.规则名&#39; => &#39;错误信息&#39;
 *
 * @var array */
 protected $message = [ &#39;phone.mobile&#39;=>&#39;phone格式错误&#39;,
 &#39;password.length&#39;=>&#39;密码长度错误&#39;
 ]; protected $scene=[ &#39;login&#39;=>[&#39;phone&#39;,&#39;password&#39;]
 ];
}
Copy after login

Open route/route.php

The code is as follows

<?php
use think
acade\Route;
Route::get(&#39;/&#39;,&#39;index/Index/index&#39;);
Route::group(&#39;account&#39;,function (){
 Route::post(&#39;/login&#39;,&#39;login/Login/login&#39;)->validate(&#39;applogin
alidateLogin&#39;,&#39;login&#39;);
});
//需要验证登录
Route::group(&#39;api&#39;,function (){
 Route::post(&#39;/user&#39;,&#39;index/Index/index&#39;);
})->middleware(apphttpmiddlewareAuth::class);
Copy after login

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=&#39;请求成功&#39;,int $code=1)
 {
 return json([
 &#39;msg&#39;=>$msg,
 &#39;data&#39;=>$data,
 &#39;code&#39;=>$code
 ]);
 }
 public static function errJsonReturn(string $msg = &#39;请求失败&#39;, int $code = 0, array $data = [])
 {
 return json([
 &#39;msg&#39;=>$msg,
 &#39;data&#39;=>$data,
 &#39;code&#39;=>$code
 ]);
 }
}
Copy after login

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 &#39;&#39; COMMENT &#39;uuid&#39;,
 `password` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT &#39;&#39; COMMENT &#39;登录密码&#39;,
 `name` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT &#39;&#39; COMMENT &#39;真实姓名&#39;,
 `nick` varchar(8) COLLATE utf8mb4_unicode_ci DEFAULT &#39;&#39; COMMENT &#39;昵称&#39;,
 `gender` enum(&#39;1&#39;,&#39;2&#39;,&#39;0&#39;) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT &#39;0&#39; COMMENT &#39;用户性别,0 表示未知,1 表示男,2 女表示女&#39;,
 `regist_time` int(11) unsigned DEFAULT NULL,
 `icon` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT &#39;&#39; COMMENT &#39;头像&#39;,
 `mobile` char(11) COLLATE utf8mb4_unicode_ci DEFAULT &#39;&#39; COMMENT &#39;手机号&#39;,
 `im_accid` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT &#39;&#39; COMMENT &#39;im账号&#39;,
 `im_icon` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT &#39;&#39; COMMENT &#39;im头像&#39;,
 `im_email` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT &#39;&#39; COMMENT &#39;im邮箱&#39;,
 `im_birth` varchar(16) COLLATE utf8mb4_unicode_ci DEFAULT &#39;&#39; COMMENT &#39;im生日&#39;,
 `im_mobile` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT &#39;&#39; COMMENT &#39;im手机号码&#39;,
 `create_time` int(11) unsigned DEFAULT &#39;0&#39;,
 `del_time` int(11) unsigned DEFAULT &#39;0&#39;,
 `is_ban` enum(&#39;0&#39;,&#39;1&#39;) COLLATE utf8mb4_unicode_ci DEFAULT &#39;0&#39; COMMENT &#39;是否封号&#39;,
 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 &#39;0&#39; COMMENT &#39;用户id&#39;,
 `token` text COLLATE utf8mb4_unicode_ci NOT NULL COMMENT &#39;登录时的令牌&#39;,
 `iat_time` int(11) DEFAULT &#39;0&#39; COMMENT &#39;登录时间&#39;,
 `ip` bigint(20) unsigned DEFAULT &#39;0&#39; COMMENT &#39;登录ip-ip2long&#39;,
 `exp_time` int(11) DEFAULT &#39;0&#39; COMMENT &#39;失效时间&#39;,
 `voe_time` int(11) DEFAULT &#39;0&#39; COMMENT &#39;token旧换新有效时间&#39;,
 KEY `login_log_uid` (`uid`,`ip`,`token`(32)) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Copy after login

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!

Related labels:
jwt
source:cnblogs.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template