小程序
app.js
import {
Cache
} from './utils/cache.js';
const cache = new Cache(7200)
// app.js
App({
onLaunch() {
// 展示本地存储能力
const logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
wx.request({
url: 'url',
method:'GET',
data:{
code:res.code
},
success:ret=>{
cache.set('token',ret.data.token)
}
})
}
})
},
globalData: {
userInfo: null
}
})
小程序缓存类
cache.js
// 缓存类
class Cache {
// 构造方法 单位秒
constructor({ expire = 3600 }) {
// 成员属性 过期时间
// 毫秒
this.expire = new Date().getTime() + expire * 1000;
}
// 设置
set(key, value) {
let data = { expire: this.expire, value };
// 设置缓存
wx.setStorageSync(key, data);
}
// 永久
forever(key, value) {
let expire = new Date().getTime() + 9999999999 * 1000;
let data = { expire, value };
// 设置缓存
wx.setStorageSync(key, data);
}
// 判断是否存在缓存
has(key) {
// 获取当前时间
let time = new Date().getTime();
// 缓存数据
let data = wx.getStorageSync(key);
if (data != '') {
if (time > data.expire) { // 缓存过期
// 删除过期缓存
wx.removeStorageSync(key);
return false;
}
return true;
}
return false;
}
// 获取
get(key) {
if (this.has(key)) {
return wx.getStorageSync(key).value;
}
return null;
}
// 删除
del(key) {
wx.removeStorageSync(key);
}
}
export {Cache}
?后台操作
ThinkPHP6+JWT 中间件校验Token时效性
如果你是第一次安装的话,在命令行下面,切换到你的WEB根目录下面并执行下面的命令:
composer create-project topthink/think tp
tp6扩展安装多应用模式
//多应用安装
composer require topthink/think-multi-app
创建应用 app目录下创建?build.php 文件 并执行命令?php think build admin ?
<?php return [ ? ? ? ? // 需要自动创建的文件 ? ? '__file__' ? => [], ? ? // 需要自动创建的目录 ? ? '__dir__' ? ?=> ['controller', 'model', 'view','service','middleware','route','validate','event'], ? ? // 需要自动创建的控制器 ? ? 'controller' => ['IndexController','Error'], ? ? // 需要自动创建的模型 ? ? 'model' ? ? ?=> ['UserModel'], ? ? // 需要自动创建的模板 ? ? 'view' ? ? ? => ['index/index'], ? ? // 需要自动创建的服务层 ? ? 'service' ? ? ? => ['IndexService'], ? ? // 需要自动创建的中间件 ? ? 'middleware' ? ? ? => ['IndexMiddleware'], ? ? // 需要自动创建的路由 ? ? 'route' ? ? ? => ['route'], ? ? // 需要自动创建的验证器 ? ? 'validate' ? ? ? => ['IndexValidate'], ? ? // 需要自动创建的事件层 ? ? 'event' ? ? ? => ['IndexEvent'], ? ?? ]; ?
view视图?
//安装视图 composer require topthink/think-view
安装JWT扩展
建议使用composer安装 方便 快捷,切到项目目录下运行以下命令
?composer require firebase/php-jwt
?ThinkPHP6.0的JWT扩展放在/vendor/firebase/php-jwt/src 目录下
?Login控制器代码
<?php
declare (strict_types = 1);
namespace app\api\controller;
use app\api\model\User;
use app\api\server\Token;
class Login
{
/**
* 小程序登录,获取token
*/
public function login()
{
//接收参数;
$code = input('code');
//获取微信授权url
$url = sprintf(config('wx.WxLoginUrl'),config('wx.AppID'),config('wx.AppSecret'),$code);
//获取openid;
$data = curlGet($url);
// print_r($data);
//查询数据库,如果有取出信息,如果没有将信息存入数据库;
$userInfo = User::where('openid',$data['openid'])->find();
if(empty($userInfo)){
$userInfo = User::create($data);
}
//获取token;
$token = (new Token())->generateToken($userInfo->id);
//返回token;
return json(['token'=>$token,'error_code'=>0,'msg'=>'登录成功']);
}
}
config下的wx.php
<?php
return [
'AppID'=>'',
'AppSecret'=>'',
'WxLoginUrl'=>'https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code'
];
?curl模拟get请求
function curlGet($url)
{
$headerArray =array("Content-type:application/json;","Accept:application/json");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headerArray);
$output = curl_exec($ch);
curl_close($ch);
$output = json_decode($output,true);
return $output;
}
生成token ,这里是把用户uid存储到data里
这里的生成token的代码放到了Server文件夹下的Token类里
验证 token ,这里的token一般用 header 方式传送,接收后直接调用
?server文件夹下的Token.php代码
<?php
namespace app\api\server;
use app\Request;
use Firebase\JWT\JWT;
class Token
{
protected $salt;
public function __construct()
{
$this->salt = config('jwt.salt');//自己随机生成的一个字符串
}
/**
* 生成token
* @param $uid
* @return mixed
*/
function generateToken($uid)
{
//获取当前时间戳
$currentTime = time();
$data = array(
"iss" => 'keZuo', //签发者 可以为空
"aud" => '', //面象的用户,可以为空
"iat" => $currentTime, //签发时间
"nbf" => $currentTime, //立马生效
"exp" => $currentTime + 7200, //token 过期时间 两小时
"data" => [ //记录的userid的信息,这里是自已添加上去的,如果有其它信息,可以再添加数组的键值对
'uid' => $uid,
]
);
//生成token
$token = JWT::encode($data, $this->salt, "HS256"); //根据参数生成了 token
return $token;
}
/**
* 校验token时效性
*/
public function chekToken($token)
{
$status=array("code"=>2);
try {
JWT::$leeway = 60;//当前时间减去60,把时间留点余地
$decoded = JWT::decode($token, $this->salt, array('HS256')); //HS256方式,这里要和签发的时候对应
$arr = (array)$decoded;
$res['code']=1;
$res['data']=$arr['data'];
return $res;
} catch(\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
$status['msg']="签名不正确";
return $status;
}catch(\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
$status['msg']="token失效";
return $status;
}catch(\Firebase\JWT\ExpiredException $e) { // token过期
$status['msg']="token失效";
return $status;
}catch(\Exception $e) { //其他错误
$status['msg']="未知错误";
return $status;
}
}
}
创建中间件,检验Token校验时效性
????????创建中间件命令:php think make:middleware CheckToken
?中间件里面的代码 CheckToken.php
<?php
declare (strict_types = 1);
namespace app\middleware;
use app\api\server\Token;
class CheckToken
{
/**
* 处理请求
*
* @param \think\Request $request
* @param \Closure $next
* @return Response
*/
public function handle($request, \Closure $next)
{
//第一步先取token
$token = $request->header('token');
//jwt进行校验token
$res = (new Token())->chekToken($token);
if ($res['code'] != 1 ){
return json(['error_code'=>999,'msg'=>$res['msg'],'data'=>''],400);
}
$request->uid = $res['data']->uid;
return $next($request);
}
}
?进行在路由文件中引入中间件验证Token
?config/middleware.php 中注册中间件
<?php
// 中间件配置
return [
// 别名或分组
'alias' => [
'check'=>[
\app\middleware\CheckToken::class
]
],
// 优先级设置,此数组中的中间件会按照数组中的顺序优先执行
'priority' => [],
];
在路由文件中进行使用
thinkphp 6 路由文件由自己写
app/api/route/route.php
这里使用分组路由进行使用中间件校验token
|