以TP6为例
在util文件夹建立api.js文件
const domain = "http://你的测试域名/";
//导出的类名
export default class Api {
req(url, data = '', method = "get") {
//判断是否需要刷新token
if (wx.getStorageSync('token') && Date.parse(new Date()) > wx.getStorageSync('expireTime')) {
wx.request({
url: 'http://www.day13.com/token/freshtoken',
header: {
token: wx.getStorageSync('token')
},
success: res => {
if (res.data.code == 0) {
wx.setStorageSync('token', res.data.data.token)
var time = Date.parse(new Date()) + res.data.data.expire
wx.setStorageSync('expireTime', time)
}
}
})
}
//两个参数为函数
return new Promise(function (resolve, reject) {
//有token则携带
let header = {}
if (wx.getStorageSync('token')) {
header.token = wx.getStorageSync('token')
}
//有openid则携带
if (wx.getStorageSync('openid')) {
header.openid = wx.getStorageSync('openid')
}
url = domain + url
console.log(url)
wx.request({
url,
data,
header,
method,
success: (res) => {
if (res.data.code == 0) {
resolve(res.data)
} else {
wx.showToast({
title: res.data.msg,
icon: "error"
})
}
},
fail: (res) => {
wx.showToast({
title: '网络错误',
})
}
})
})
}
}
封装使用
封装api接口 后期直接调用访问网络请求
//引入文件
import Api from '../../utils/api.js'
//实例化类
let api = new Api()
使用
onLoad: function (options) {
api.req('index', '', 'GET').then(res => {
this.setData({
// img:res.data.img
})
})
},
PHP生成token依赖
composer require firebase/php-jwt
common.php 代码
<?php
// 这是系统自动生成的公共文件
use \Firebase\JWT\JWT;
//生成验签
function signToken($uid){
$key='!@#$%*&'; //这里是自定义的一个随机字串,应该写在config文件中的,解密时也会用,相当 于加密中常用的 盐 salt
$token=array(
"iss"=>$key, //签发者 可以为空
"aud"=>'', //面象的用户,可以为空
"iat"=>time(), //签发时间
"nbf"=>time(),
"exp"=> time()+60, //token 过期时间
"data"=>[ //记录的userid的信息,这里是自已添加上去的,如果有其它信息,可以再添加数组的键值对
'uid'=>$uid,
]
);
// print_r($token);
$jwt = JWT::encode($token, $key, "HS256"); //根据参数生成了 token
return $jwt;
}
//验证token
function checkToken($token){
$key='!@#$%*&';
$status=array("code"=>2);
try {
JWT::$leeway = 60;//当前时间减去60,把时间留点余地
$decoded = JWT::decode($token, $key, 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;
}
}
app.js获取token
//引入文件
import Api from './utils/http'
//实例化类
let api = new Api()
App({
onLaunch() {
// 展示本地存储能力
const logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
if (!wx.getStorageSync('token')) {
api.req('token', '', 'GET').then(res => {
if (res.code == 0) {
wx.setStorageSync('token', res.data.token)
var time = Date.parse(new Date())+res.data.expire
wx.setStorageSync('expireTime', time)
console.log(wx.getStorageSync('expireTime'))
console.log(Date.parse(new Date()))
}
})
}
},
globalData: {
userInfo: null
}
})
php tp6生成token
public function gettoken()
{
//模拟用户id
$uid = 1;
//生成token
$token = signToken($uid);
$arr['token'] = $token;
//多久过期
$arr['expire'] = 180 * 1000; //过期时间是生成token设置的
Cache::set($token, $uid, 200);
return json(['code' => 0, 'data' => $arr, 'msg' => '获取token成功']);
}
刷新token
public function freshtoken()
{
$token=request()->header("token");
$uid= Cache::get("$token");
$token = signToken($uid);
$arr['token']=$token;
$arr['expire']=180*1000; //微信小程序时间戳为毫秒×1000
Cache::set($token, $uid, 200);
return json(['code'=>0,'data'=>$arr,'msg'=>'获取token成功']);
}
中间件
public function handle($request, \Closure $next)
{
//
$token = $request->header('token');
$res = checkToken($token);
if ($res['code']==1){
return $next($request);
}
else{
return json(['code'=>1,'data'=>'','msg'=>'token失效']);
}
}
在这里插入图片描述
注意的是 token的过期时间要和给定返回为接口的过期时间一致,不然会友好提示token过期