Heim > PHP-Framework > Denken Sie an PHP > thinkPHP-Konfigurations-JWT (Codebeispiel)

thinkPHP-Konfigurations-JWT (Codebeispiel)

L
Freigeben: 2020-05-27 13:48:39
nach vorne
6281 Leute haben es durchsucht

thinkPHP-Konfigurations-JWT (Codebeispiel)

Installation und Verwendung von thinkphp5.1-jwt

Installieren Sie das JWT-Plug-in

Fügen Sie es zur Anforderung hinzu in Composer.json Konfigurieren Sie Folgendes:

"firebase/php-jwt": "^5.0"

und führen Sie das Composer-Update im Projektstammverzeichnis aus

Erstellen Sie eine Authentifizierungs-Middleware

php think make:middleware Auth

Öffnen Sie die httpmiddlewareAuth-Datei der Anwendung

<?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);
 }
}
Nach dem Login kopieren

Erstellen Sie eine Controller-Anmeldung
php think make:controller login/Login --plain
Der Code lautet wie folgt

<?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()
 ]);
 }
}
Nach dem Login kopieren

Erstellen Sie einen neuen gemeinsamen Ordner unter der Anwendung und einen neuen Dienst im gemeinsamen Ordner, erstellen Sie

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];
 }
}
Nach dem Login kopieren

Hängen Sie Parameter am Ende des config/app.php-Dokuments an und übernehmen Sie die Fehlerkontrolle

// 异常处理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()); 
} 
},
Nach dem Login kopieren

Installation und Verwendung von thinkphp5.1-jwt und Überprüfung der Routing-Parameter

Erstellen Sie eine neue TokenException.php unter thinkphplibrary hinkException

Der Code lautet wie folgt

<?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;
 }
}
Nach dem Login kopieren

Erstellen Sie einen Login-Authentifikator

php think make:validate login/Login

Der Code lautet wie folgt

<?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;]
 ];
}
Nach dem Login kopieren

Öffnen Sie route/route.php

Der Code lautet wie folgt

<?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);
Nach dem Login kopieren

Die Middleware hier kann laut offizieller Dokumentation in middleware.php registriert werden, beim Test wurde jedoch ein Problem festgestellt. Die Route führt die Middleware-Methode nicht aus . Beim Zugriff wird die gesamte in middleware.php registrierte Middleware nacheinander von oben nach unten ausgeführt. Schreiben Sie sie daher als middleware(apphttpmiddlewareAuth::class); um, um Middleware zum Erstellen einer neuen help.php unter common zu verwenden Der Code lautet wie folgt

<?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
 ]);
 }
}
Nach dem Login kopieren

Gehen Sie zur Datenbank, um eine neue Datenbank zu erstellen und erstellen Sie zwei Tabellen

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;
Nach dem Login kopieren

Empfohlenes Tutorial: „

TP5

Das obige ist der detaillierte Inhalt vonthinkPHP-Konfigurations-JWT (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
jwt
Quelle:cnblogs.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage