静默登录
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: "POST",
data: {
code: res.code
},
success: (result) => {
console.log(result);
wx.setStorage({
key: 'open_id',
data: result.data.data.open_id
})
wx.setStorage({
key: 'token',
data: result.data.data.token
})
},
})
// 发送 res.code 到后台换取 openId, sessionKey, unionId
}
})
},
globalData: {
userInfo: null
}
})
封装curl config
return [
"url"=>"https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
'AppID'=>'',//自己的微信小程序appsecret
"AppSecret"=>'',//自己的微信小程序appsecret
];
封装curl
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;
}
tp6 控制器
public function login(Request $request){
//获取code码
$code = $request->post('code'); //var_dump($code);die();
//获取微信授权url
$url = sprintf(config('wx.url'),config('wx.AppID'),config('wx.AppSecret'),$code);
//获取openid
$data = json_decode(file_get_contents($url));
$data = (array)$data;
//进行查询数据库里面是否有该用户,如果没有,则进行新增
$user = User::where('open_id',$data['openid'])->find();
//如果没有用户进行创建
if (empty($user)){
$user = User::insert([
'open_id'=>$data['openid'],
'session_key'=>$data['session_key'],
]);
}
//生成token,保存用户登录状态
$token = (new \app\home\service\JWT())->getToken($user->id);
return success(['token'=>$token,'open_id'=>$data['openid']]);
}
tp6 中间件
//中间件验证token 和 接口并发 恶意请求问题的解决
public function handle($request, \Closure $next)
{
$token = $request->header('token');
try{
$userId = JWT::getUserId($token);
if (!$userId){
return fail('token不存在');
}
$requestLimit = Cache::store('redis')->get($request->ip() . '_' . $userId);
if ($requestLimit) {
// 存在判断当前数量是否大于20次
if ($requestLimit > 20) {
throw new Exception('操作过快');
} else {
// 当前操作数量不大于20次则自增1次
Cache::store('redis')->inc($request->ip() . '_' . $userId,1);
}
} else {
// 不存在记录当前ip下用户操作次数,有效期1分钟内
Cache::store('redis')->set($request->ip() . '_' . $userId,1,60);
}
}catch (\Exception $e){
return fail('内部错误');
}
return $next($request);
}
安装 JWT
composer require lcobucci/jwt 3.3
JWT 封装
<?php
/**
* Created by PhpStorm.
* User: HentHao
* Date: 2022/2/19
* Time: 9:30
*/
namespace app\home\service;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\ValidationData;
class JWT
{
private static $_config = [
'audience' => 'http://www.pyg.com',//接收人
'id' => '3f2g57a92aa',//token的唯一标识,这里只是一个简单示例
'sign' => 'pinyougou',//签名密钥
'issuer' => 'http://adminapi.pyg.com',//签发人
'expire' => 3600 * 24 //有效期
];
//生成token
public static function getToken($user_id)
{
//签名对象
$signer = new Sha256();
//获取当前时间戳
$time = time();
//设置签发人、接收人、唯一标识、签发时间、立即生效、过期时间、用户id、签名
$token = (new Builder())->issuedBy(self::$_config['issuer'])
->canOnlyBeUsedBy(self::$_config['audience'])
->identifiedBy(self::$_config['id'], true)
->issuedAt($time)
->canOnlyBeUsedAfter($time - 1)
->expiresAt($time + self::$_config['expire'])
->with('user_id', $user_id)
->sign($signer, self::$_config['sign'])
->getToken();
return (string)$token;
}
//从请求信息中获取token令牌
public static function getRequestToken()
{
if (empty($_SERVER['HTTP_AUTHORIZATION'])) {
return false;
}
$header = $_SERVER['HTTP_AUTHORIZATION'];
$method = 'bearer';
//去除token中可能存在的bearer标识
return trim(str_ireplace($method, '', $header));
}
//从token中获取用户id (包含token的校验)
public static function getUserId($token = null)
{
$user_id = null;
$token = empty($token) ? self::getRequestToken() : $token;
if (!empty($token)) {
//为了注销token 加以下if判断代码
$delete_token = cache('delete_token') ?: [];
if (in_array($token, $delete_token)) {
//token已被删除(注销)
return $user_id;
}
$token = (new Parser())->parse((string)$token);
//验证token
$data = new ValidationData();
$data->setIssuer(self::$_config['issuer']);//验证的签发人
$data->setAudience(self::$_config['audience']);//验证的接收人
$data->setId(self::$_config['id']);//验证token标识
if (!$token->validate($data)) {
//token验证失败
return $user_id;
}
//验证签名
$signer = new Sha256();
if (!$token->verify($signer, self::$_config['sign'])) {
//签名验证失败
return $user_id;
}
//从token中获取用户id
$user_id = $token->getClaim('user_id');
}
return $user_id;
}
}
中间件获取token header获取token
wx.request({
url: 'url',
header: {
'context-type':'application/json',
'token': wx.getStorageSync('token')//后端能够获取token
},
success(res){
console.log(res);
let hotel = res.data.data;
//渲染数据
_this.setData({
hotel
})
}
})