<?php
namespace App\Http\Middleware;
use App\Services\Common\CurlService;
use App\Wechat\WechatParam;
use Closure;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
/**
* 公众号检查,获取支付openid
* Class OfficialCheck
* @package App\Http\Middleware
* Auth Zhong
* Date 2019/2/22
*/
class WechatCheck
{
/**
* OfficialCheck constructor.
*/
public function __construct()
{
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
//获取jsapi_ticket
$jsapi_ticket = Cache::get('wechat_jsapi_ticket');
if (empty($jsapi_ticket)) {
$jsapi_ticket = $this->_getJsApiTicket();
if (empty($jsapi_ticket)) {
return $next($request);
}
}
//生成配置
$timestamp = time();
$noncestr = $this->_generateNonceStr();
$url = $request->getUri();
$ret = strpos($url, '#');
if ($ret) {
$url = substr($url, 0, $ret);
}
$url = trim($url);
if (empty($url))
return $next($request);
$arrdata = ["timestamp" => $timestamp, "noncestr" => $noncestr, "url" => $url, "jsapi_ticket" => $jsapi_ticket];
$sign = $this->_getSignature($arrdata);
if (!$sign)
return $next($request);
WechatParam::instance()->merge([
"nonceStr" => $noncestr,
"timestamp" => $timestamp,
"url" => $url,
"signature" => $sign,
]);
return $next($request);
}
/**
* 获取jsapi_ticket
*/
private function _getJsApiTicket()
{
$access_token = $this->_getAccessToken();
if (empty($access_token)) {
return null;
}
$curl = new CurlService();
$res = $curl->get('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' . $access_token . '&type=jsapi');
if (!empty($res)) {
if (isset($res->ticket)) {
Cache::put("wechat_jsapi_ticket", $res->ticket, 100);
return $res->ticket;
}
}
return null;
}
/**
* 获取access_token
*/
private function _getAccessToken()
{
$access_token = Cache::get('wechat_access_token');
if (empty($access_token)) {
$curl = new CurlService();
$wechat = WechatParam::instance()->getParam();
$res = $curl->get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$wechat['appid']}&secret={$wechat['appsecret']}");
if (!empty($res)) {
// Log::info('获取token:' . json_encode($res));
if (isset($res->access_token)) {
Cache::put("wechat_access_token", $res->access_token, 100);
return $res->access_token;
}
}
return null;
}
return $access_token;
}
/**
* 生成随机字串
* @param number $length 长度,默认为16,最长为32字节
* @return string
*/
private function _generateNonceStr($length = 16)
{
// 密码字符集,可任意添加你需要的字符
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $str;
}
/**
* 获取签名
* @param array $arrdata 签名数组
* @param string $method 签名方法
* @return boolean|string 签名值
*/
private function _getSignature($arrdata, $method = "sha1")
{
if (!function_exists($method)) return false;
ksort($arrdata);
$paramstring = "";
foreach ($arrdata as $key => $value) {
if (strlen($paramstring) == 0)
$paramstring .= $key . "=" . $value;
else
$paramstring .= "&" . $key . "=" . $value;
}
$Sign = $method($paramstring);
return $Sign;
}
}