ホームページ > PHPフレームワーク > ThinkPHP > thinkPHP 設定 jwt (コード例)

thinkPHP 設定 jwt (コード例)

L
リリース: 2020-05-27 13:48:39
転載
6276 人が閲覧しました

thinkPHP 設定 jwt (コード例)

thinkphp5.1-jwt のインストールと使用

jwt プラグインをインストールします

require に追加しますコンポーザー.json 内で次のように設定します。

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

プロジェクトのルート ディレクトリでコンポーザーの更新を実行します。

認証ミドルウェアの作成

php think make:middleware Auth

アプリケーションを開くhttpmiddlewareAuth ファイル

<?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);
 }
}
ログイン後にコピー

コントローラー ログインの作成
php think make:controller login/Login --plain
コードは次のとおりです

<?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()
 ]);
 }
}
ログイン後にコピー

application の下に新しい共通フォルダーを作成し、common の下に新しいサービス フォルダーを作成し、サービス フォルダー

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];
 }
}
ログイン後にコピー

config/app.php ドキュメントの最後にパラメータを追加し、エラー制御を引き継ぎます

// 异常处理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()); 
} 
},
ログイン後にコピー

thinkphp5.1-jwt のインストール、使用、およびルーティング パラメーターの検証

thinkphplibrary hinkException の下に新しい TokenException.php を作成します

コードは次のとおりです

<?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;
 }
}
ログイン後にコピー

ログインバリデータの作成

php think make:validate login/Login

コードは次のとおりです

<?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;]
 ];
}
ログイン後にコピー

ルート/ルートを開きます。 php

コードは次のとおりです

<?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);
ログイン後にコピー

ここでのミドルウェアは公式ドキュメントに従ってmiddleware.phpに登録できますが、テスト中に問題が見つかりました。ルートはmiddlewareメソッドにアクセスすると、middleware.phpに登録されている全てのミドルウェアが上から順に実行されるので書き換えられます Middleware(apphttpmiddlewareAuth::class);の場合はミドルウェアを使用してcommon

の下に新しいhelp.phpを作成

コードは次のとおりです

<?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
 ]);
 }
}
ログイン後にコピー

データベースに新しいデータベースを作成し、2つの新しいテーブルを作成します

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;
ログイン後にコピー

推奨チュートリアル: "TP5"

以上がthinkPHP 設定 jwt (コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
jwt
ソース:cnblogs.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート