thinkphp6 jwt
文章描述:
token一般是用户在输入账号密码登录后生成的再次请求验证秘钥
token优势
支持跨域访问:cookie是无法跨域的,而token由于没有用到cookie(前提是将token放到请求头中),所以跨域后不会存在信息丢失问题
无状态:token机制在服务端不需要存储session信息,因为token自身包含了所有登录用户的信息,所以可以减轻服务端压力
安装
Thinkphp6
在WEB根目录下面并执行下面的命令
composer create-project topthink/think tp6
多应用
composer require topthink/think-multi-app
JWT扩展
composer require firebase/php-jwt
应用
建后台应用
php think build admin
建立前台应用
php think build api
在应用控制器下面新建公用Controller.php
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use app\BaseController;
use think\response\Json;
class Controller extends BaseController
{
/**
* 初始化
*/
public function initialize()
{
//拦截验证
//do something
}
/**
* 返回封装后的 API 数据到客户端
*/
protected function renderData(int $status = null, string $message = '', array $data = []): Json
{
is_null($status) && $status = config('status.success');
return json(compact('status', 'message', 'data'));
}
/**
* 返回操作成功json
* @param array|string $data
* @param string $message
* @return Json
*/
protected function renderSuccess($data = [], string $message = 'success'): Json
{
if (is_string($data)) {
$message = $data;
$data = [];
}
return $this->renderData(200, $message, $data);
}
/**
* 返回操作失败json
* @param string $message
* @param array $data
* @return Json
*/
protected function renderError(string $message = 'error', array $data = []): Json
{
return $this->renderData(500, $message, $data);
}
/**
* 获取post数据 (数组)
* @param $key
* @return mixed
*/
protected function postData($key = null)
{
return $this->request->post(empty($key) ? '' : "{$key}/a");
}
/**
* 获取post数据 (数组)
* @param string $key
* @return mixed
*/
protected function postForm(string $key = 'form')
{
return $this->postData($key);
}
/**
* 获取post数据 (数组)
* @param $key
* @return mixed
*/
protected function getData($key = null)
{
return $this->request->get(is_null($key) ? '' : $key);
}
}
然后再加上 jwt 的公用方法,在commen.php里面写
<?php
// 应用公共文件
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\SignatureInvalidException;
const JWT_TTL = 7200;
/**生成验签
* @param $data
* @return string
*/
function signToken($data) :string
{
$key='LAL@lc!'; //这里是自定义的一个随机字串,应该写在config文件中的,解密时也会用,相当于加密中常用的 盐-salt
$token=array(
"iss" => $key, //签发者 可以为空
"aud" => '', //面象的用户,可以为空
"iat" => time(), //签发时间
"nbf" => time() + 3, //在什么时候jwt开始生效 (这里表示生成100秒后才生效)
"exp"=> time() + JWT_TTL, //token 过期时间
"data"=> $data //记录的userid的信息,这里是自已添加上去的,如果有其它信息,可以再添加数组的键值对
);
return JWT::encode($token, $key, "HS384"); //根据参数生成了token,可选:HS256、HS384、HS512、RS256、ES256等
}
/**验证token
* @param $token
* @return array|int[]
*/
function checkToken($token) :array
{
$key = 'LAL@lc!';
$status = ['code' => 500];
try {
JWT::$leeway = 60;//当前时间减去60,把时间留点余地
$decoded = JWT::decode($token, new Key($key, 'HS384')); //同上的方式,这里要和签发的时候对应
$arr = (array)$decoded;
$res['code'] = 200;
$res['data'] = $arr['data'];
$res['data'] = json_decode(json_encode($res['data']), true);//将stdObj类型转换为array
return $res;
} catch (SignatureInvalidException $e) { //签名不正确
$status['msg'] = "签名不正确";
return $status;
} catch (BeforeValidException $e) { // 签名在某个时间点之后才能用
$status['msg'] = "token失效";
return $status;
} catch (ExpiredException $e) { // token过期
$status['msg'] = "token失效";
return $status;
} catch (Exception $e) { //其他错误
$status['msg'] = "未知错误";
return $status;
}
}
在admin应用的controller/Index
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use think\response\Json;
class Index extends Controller
{
public function index():Json
{
$data = [
'id' => 1,
'info' => array('username' => '小坏蛋','age'=>22,'email'=>'123456@qq.com')
];
$data['token'] = signToken($data);
return $this->renderSuccess($data);
}
public function check():Json
{
$token = $this->request->header('token');
$user_info = checkToken($token);
if($user_info['code'] != 200){
return $this->renderError('token验证失败');
}
return $this->renderSuccess($user_info,'验证成功');
}
}
发布时间:2023/11/16
发表评论