thinkPHP配置jwt(代碼實例)

thinkPHP配置jwt(代碼實例)

thinkphp5.1-jwt的安裝與使用

安裝jwt插件

composer.jsonrequire中加入如下配置

“firebase/php-jwt”: “^5.0”

在項目根目錄下執行composer update即可.

立即學習PHP免費學習筆記(深入)”;

創建一個auth中間件

php think make:middleware Auth

打開applicationhttpmiddlewareAuth文件

<?php namespace apphttpmiddleware; use FirebaseJWTJWT; use FirebaseJWTSignatureInvalidException; use thinkexceptionTokenException; use thinkexceptionValidateException; use think acadeCache; use think acadeConfig;  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-&gt;param('token')?!==?null)?{ ?$token?=?$request-&gt;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-&gt;voe?exp?&gt;?time())?{ ?throw?new?TokenException('請換取新令牌',?402); ?}?else?if?($de_token-&gt;voe?get('token_'?.?$de_token-&gt;data-&gt;uid)?!=?$token)?{ ?throw?new?TokenException('用戶信息錯誤,請重新登錄',?401); ?} ?if?($de_token-&gt;data-&gt;is_ban?==?1)?{ ?throw?new?ValidateException('該賬戶已被封禁'); ?} ?$request-&gt;auth?=?$de_token-&gt;data-&gt;uid; ?return?$next($request); ?} }

創建一個控制器Login
php think make:controller login/Login –plain
代碼如下

<?php namespace applogincontroller; use appcommonhelp; use appcommonserviceOperationToken; use thinkController; use thinkDb; use thinkRequest; class Login extends Controller {  public function login(Request $request)  {  $info = Db::name(&#39;user&#39;)->field('id,uuid,nick,gender,icon,im_accid,im_icon,is_ban')-&gt;where('del_time',?'=',?'0')-&gt;where(['mobile'?=&gt;?$request-&gt;param('phone'),?'password'?=&gt;?md5($request-&gt;param('password'))])-&gt;findOrEmpty(); ?if?($info?==?null?||?empty($info))?{ ?return?help::errJsonReturn('賬號或密碼錯誤'); ?} ?$token?=?OperationToken::crearToken($info['id'],?$info['uuid'],?$info['is_ban']); ?return?json([ ?'type'?=&gt;?'Bearer?', ?'access_token'=&gt;$token['token'], ?'exp_time'=&gt;$token['exp'], ?'voe_time'=&gt;$token['voe'], ?'iat_time'=&gt;time() ?]); ?} }

在application下新建common文件夾,在common下新建service文件夾,service文件夾下創建

OperationToken.php

<?php namespace appcommonservice; use thinkDb; use think acadeCache; use FirebaseJWTJWT; use think acadeConfig; class OperationToken {  public static function crearToken(int $uid, string $uuid, int $is_ban): array  {  $time = time();  $info_token = [  &#39;iat&#39; =>?$time,//簽發時間 ?'voe'?=&gt;?Config::get('TOKEN_VOE',7200)?+?$time,//換取有效時間 ?'exp'?=&gt;?Config::get('TOKEN_EXP',3600)+$time,//有效時間 ?'sign'?=&gt;?base64_encode($uuid),//簽名 ?'data'?=&gt;?[ ?'uid'?=&gt;?$uid,//用戶id ?'is_ban'?=&gt;?$is_ban,//是否被禁用 ?] ?]; ?$token?=?JWT::encode($info_token,?Config::get('JWT_KEY')); ?Cache::tag('login')-&gt;set('token_'?.?$uid,?$token,?Config::get('TOKEN_VOE',7200)?+?$time); ?Db::name('user_login_log')-&gt;insert( ?[ ?'uid'=&gt;$uid, ?'token'=&gt;$token, ?'iat_time'=&gt;$time, ?'ip'=&gt;ip2long(request()-&gt;ip()), ?'exp_time'=&gt;Config::get('TOKEN_EXP',3600)+$time, ?'voe_time'=&gt;?Config::get('TOKEN_VOE',7200)?+?$time ?] ?); ?return?[ ?'token'=&gt;$token,? ?'voe'?=&gt;Config::get('TOKEN_VOE',7200)?+?$time, ?'exp'?=&gt;?Config::get('TOKEN_EXP',3600)+$time]; ?} }

?

config/app.php文檔末尾追加參數并接管錯誤控制

//?異常處理handle類?留空使用?thinkexceptionHandle 'exception_handle'?=&gt;?function?($e)?{ ?//參數驗證錯誤 ?if?($e?instanceof?thinkexceptionValidateException)?{ ?return?json(['msg'?=&gt;?$e-&gt;getError()],?422); ?} ?//route未定義 ?if?($e?instanceof?thinkexceptionValidateException)?{ ?return?json(['msg'?=&gt;?$e-&gt;getMessage()],?404); ?}?//token過期/無效?401-令牌/賬號密碼錯誤?402-令牌過期可舊換新?403-無權限訪問 ?if?($e?instanceof?hinkexceptionTokenException)?{ ?return?json(['msg'?=&gt;?$e-&gt;getError()],?$e-&gt;getCode()); ?}?//?請求異常 ?if?($e?instanceof?HttpException?&amp;&amp;?request()-&gt;isAjax())?{ ?return?response(['msg'?=&gt;?$e-&gt;getMessage()],?$e-&gt;getStatusCode());? }? },

thinkphp5.1-jwt的安裝與使用與路由參數驗證

在thinkphplibrary?hinkexception下新建TokenException.php

代碼如下

<?php namespace thinkexception; class TokenException extends HttpException {  protected $error;  public function __construct($error, $code = 0)  {  $this->error?=?$error; ?$this-&gt;message?=?$error; ?$this-&gt;code?=?$code; ?} ?/** ?*?獲取驗證錯誤信息 ?*?@access?public ?*?@return?array|string ?*/ ?public?function?getError() ?{ ?return?$this-&gt;error; ?} }

創建一個login的驗證器

php think make:validate login/Login

代碼如下

<?php namespace applogin validate;use thinkValidate;class Login extends Validate { /**  * 定義驗證規則  * 格式:&#39;字段名&#39; =>?['規則1','規則2'...] ?* ?*?@var?array?*/ ?protected?$rule?=?[?'phone'=&gt;'require|mobile', ?'password'=&gt;'require|length:4,12' ?];? ?/** ?*?定義錯誤信息 ?*?格式:'字段名.規則名'?=&gt;?'錯誤信息' ?* ?*?@var?array?*/ ?protected?$message?=?[?'phone.mobile'=&gt;'phone格式錯誤', ?'password.length'=&gt;'密碼長度錯誤' ?];?protected?$scene=[?'login'=&gt;['phone','password'] ?]; }

打開route/route.php

代碼如下

<?php use think acadeRoute; 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('applogin alidateLogin','login'); }); //需要驗證登錄 Route::group('api',function?(){ ?Route::post('/user','index/Index/index'); })-&gt;middleware(apphttpmiddlewareAuth::class);

這里的middleware按照官方文檔是可以注冊到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, ?'data'=&gt;$data, ?'code'=&gt;$code ?]); ?} ?public?static?function?errJsonReturn(string?$msg?=?'請求失敗',?int?$code?=?0,?array?$data?=?[]) ?{ ?return?json([ ?'msg'=&gt;$msg, ?'data'=&gt;$data, ?'code'=&gt;$code ?]); ?} }

數據庫中新建一個數據庫,新建兩張表

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;

推薦教程:《TP5

? 版權聲明
THE END
喜歡就支持一下吧
點贊12 分享