thinkphp5.1-jwt的安裝與使用


thinkphp5.1-jwt的安裝與使用

開發環境是在win7下.

安裝好phpstudy.--選擇php7.2+nginx

安裝好composer.

將php,composer配置到環境變量.

-----Path:C:phpStudyPHPTutorialphpphp-7.2.1-nts;C:phpStudyPHPTutorial oolscomposer;

IDE:Phpstrom

測試工具:postman

composer切換源

 composer config -g repo.packagist composer https://packagist.laravel-china.org

切換到項目目錄安裝tp--當前安裝的版本號是5.1.30

composer create-project topthink/think appname

打開phpstudy執行 其他菜單選項->軟件設置->端口常規設置

---把nginx項目下的網站目錄改成 項目目錄地址/appname/public 點擊應用重啟整個phpstudy

打開瀏覽器輸入127.0.0.1即可看到tp5的首頁.

隱藏index.php

打開phpstudy執行 其他菜單選項->打開配置文件->nginx-conf修改成如下內容

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

nginx-conf

安裝jwt插件

在composer.json的require中加入如下配置

"firebase/php-jwt": "^5.0"
或者終端窗口輸入 composer require firebase/php-jwt

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

創建一個auth中間件

php think make:middleware Auth

打開applicationhttpmiddlewareAuth文件

<?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);

 }

}

創建一個控制器Login
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('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()

 ]);

 }

}

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

 

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];

 }

}


 

config/app.php文檔末尾追加參數並接管錯誤控制
// 異常處理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的安裝與使用與路由參數驗證

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;

 }

}

創建一個login的驗證器

 

php think make:validate login/Login

代碼如下

<?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']

 ];

}

打開route/route.php

代碼如下

<?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);

這里的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='請求成功',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 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;

至此完成真個前期的搭建.

 

打開postman

 

選擇post 地址http://127.0.0.1/account/login

 

body里添加鍵值 phone,password點擊send----(自行測試參數錯誤)

 

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

返回數據

 

access_token復制過來地址修改為http://127.0.0.1/api/user

 

選擇Authorization,type切換為bearer token,在Token中填入復制過來的access_token點擊send即可看到index模塊中Index方法中的內容

 

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

Token刪除則返回如下內容

 

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

以上就是thinkphp5.1-jwt的安裝與使用與路由參數驗證,希望這篇文章對您有所幫助!

http://www.thinkphpedu.com

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM