first commit

This commit is contained in:
编码猿
2024-09-27 01:32:49 +08:00
commit 28ebe05a64
7399 changed files with 1174529 additions and 0 deletions

View File

@@ -0,0 +1,180 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/5/25 0025
* Time: 16:47
*/
namespace app\api\service;
use app\lib\exception\ParamException;
use think\Exception;
use app\api\model\User as UserModel;
use think\facade\Cache;
class UserToken extends Token
{
protected $code;
protected $wxLoginUrl;
protected $wxAppID;
protected $wxAppSecret;
function __construct($code)
{
$this->code = $code;
$this->wxAppID = config('wx.app_id');
$this->wxAppSecret = config('wx.app_secret');
$this->wxLoginUrl = sprintf(
config('wx.login_url'), $this->wxAppID, $this->wxAppSecret, $this->code);
}
/**
* 登陆
* 思路1每次调用登录接口都去微信刷新一次session_key生成新的Token不删除久的Token
* 思路2检查Token有没有过期没有过期则直接返回当前Token
* 思路3重新去微信刷新session_key并删除当前Token返回新的Token
*/
public function get($paramPost)
{
$result = curl_get($this->wxLoginUrl);
// 注意json_decode的第一个参数true
// 这将使字符串被转化为数组而非对象
$wxResult = json_decode($result, true);
if (empty($wxResult)) {
// 为什么以empty判断是否错误这是根据微信返回
// 规则摸索出来的
// 这种情况通常是由于传入不合法的code
throw new ParamException([
'code'=>401,
'msg' => '获取session_key及openID时异常微信内部错误',
'errorCode' => 10001
]);
}
else {
// 建议用明确的变量来表示是否成功
// 微信服务器并不会将错误标记为400无论成功还是失败都标记成200
// 这样非常不好判断只能使用errcode是否存在来判断
$loginFail = array_key_exists('errcode', $wxResult);
if ($loginFail) {
$this->processLoginError($wxResult);
}
else {
return $this->grantToken($wxResult,$paramPost);
}
}
}
// 颁发令牌
// 只要调用登陆就颁发新令牌
// 但旧的令牌依然可以使用
// 所以通常令牌的有效时间比较短
// 目前微信的express_in时间是7200秒
// 在不设置刷新令牌refresh_token的情况下
// 只能延迟自有token的过期时间超过7200秒目前还无法确定在express_in时间到期后
// 还能否进行微信支付
// 没有刷新令牌会有一个问题,就是用户的操作有可能会被突然中断
private function grantToken($wxResult)
{
// 此处生成令牌使用的是TP5自带的令牌
// 如果想要更加安全可以考虑自己生成更复杂的令牌
// 比如使用JWT并加入盐如果不加入盐有一定的几率伪造令牌
$openid = $wxResult['openid'];
$user = UserModel::getByOpenID($openid);
if (!$user)
// 借助微信的openid作为用户标识
// 但在系统中的相关查询还是使用自己的uid
{
$uid = $this->newUser($openid);
}
else {
$uid = $user->id;
}
$cachedValue = $this->prepareCachedValue($wxResult, $uid);
$token = $this->saveToCache($cachedValue);
return $token;
}
private function newUser($openid){
$user = UserModel::create([
'openid' =>$openid
]);
return $user->id;
}
//生成token并缓存
private function saveToCache($wxResult){
$key = self::generateToken();
$value = json_encode($wxResult);
$request = Cache::store('redis')->set($key,$value,2592000);
if(!$request){
throw new ParamException([
'code' => 401,
'msg' => '服务起缓存异常',
'errorCode' => 10001
]);
}
return $key;
}
//缓存数据预处理
private function prepareCachedValue($wxResult, $uid)
{
$cachedValue = $wxResult;
$cachedValue['uid'] = $uid;
return $cachedValue;
}
private function processLoginError($wxResult){
throw new ParamException([
'msg' => $wxResult['errmsg'],
'errorCode' => $wxResult['errcode']
]);
}
/**
* 过滤微信昵称的特殊表情
* @param $text
* @param string $replaceTo
* @return null|string|string[]
*/
public function filterEmoji($text, $replaceTo = 'x'){
$clean_text = "";
// Match Emoticons
$regexEmoticons = '/[\x{1F600}-\x{1F64F}]/u';
$clean_text = preg_replace($regexEmoticons, $replaceTo, $text);
// Match Miscellaneous Symbols and Pictographs
$regexSymbols = '/[\x{1F300}-\x{1F5FF}]/u';
$clean_text = preg_replace($regexSymbols, $replaceTo, $clean_text);
// Match Transport And Map Symbols
$regexTransport = '/[\x{1F680}-\x{1F6FF}]/u';
$clean_text = preg_replace($regexTransport, $replaceTo, $clean_text);
// Match Miscellaneous Symbols
$regexMisc = '/[\x{2600}-\x{26FF}]/u';
$clean_text = preg_replace($regexMisc, $replaceTo, $clean_text);
// Match Dingbats
$regexDingbats = '/[\x{2700}-\x{27BF}]/u';
$clean_text = preg_replace($regexDingbats, $replaceTo, $clean_text);
return $clean_text;
}
/**
* 非小程序登录token
* @param $arr
* @return string
* @throws ParamException
*/
public function LoginToken($str)
{
$token = $this->saveToCache($str);
return $token;
}
}