慕容的工作随笔

慕容的工作随笔

记录学习和工作

thinkphp5.1-jwt的安装与使用

转自:https://www.cnblogs.com/qxandxt/p/12696172.html

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

评论 (0)

还没有评论,来做第一个吧。

发表评论

提交后需管理员审核通过后显示