thinkphp5.1-jwt的安装与使用

2021-03-22 20:24

阅读:565

标签:无权限   pass   项目   auto   path   fir   tee   php5   time   

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

 

thinkphp5.1-jwt的安装与使用

标签:无权限   pass   项目   auto   path   fir   tee   php5   time   

原文地址:https://www.cnblogs.com/qxandxt/p/12696172.html


评论


亲,登录后才可以留言!