Common

<?php
namespace Proxy\Action; use Think\Action;
use Vendor\Func\Red; class CommonAction extends Action
{
public $red;
public function _initialize(){
$this->red = Red::create();
header('Content-type: text/html; charset=utf-8');
} /**
* 错误的json
* @param $code
* @param string $message
* @param array $data
*/
public function jsonError($code, $message = 'error', $data = [])
{
$returnData = [
'code' => $code,
'message' => $message,
'data' => $data
]; header('Content-type:application/json;charset=utf-8');
echo json_encode($returnData);
exit; } /**
* 正确的json
* @param int $code
* @param string $message
* @param array $data
*/
public function jsonSuccess($code = 1, $message = 'success', $data = [])
{
$returnData = [
'code' => $code,
'message' => $message,
'data' => $data
]; header('Content-type:application/json;charset=utf-8');
echo json_encode($returnData);
exit; } /**
* 设置Redis
* @param $k
* @param $v
* @param int $expires
* @return mixed
*/
public function setCache($k, $v, $expires = -1)
{
if ($expires === -1) {
return $this->red->set($k, $v);
} else {
return $this->red->setex($k, $expires, $v);
}
} /**
* 获取Redis
* @param $k
* @return mixed
*/
public function getCache($k)
{
return $this->red->get($k);
} /**
* 删除Redis
* @param $k
* @return mixed
*/
public function delCache($k)
{
return $this->red->delete($k);
} /**
* 获取过期时间
* @param $k
* @return bool
*/
public function getCacheTtl($k)
{
$ttl = $this->red->ttl($k);
if ($ttl != '-2') {
return $ttl;
} else {
return false;
}
} /**
* 检查是否存在
* @param $k
* @return mixed
*/
public function cacheExists($k)
{
return $this->red->exists($k);
}
}

AccessToken

<?php
namespace Proxy\Action; use Vendor\Func\Http; /***
* 基础支持的access_token,每日两千次
* @package Proxy\Action
*/
class AccessTokenAction extends CommonAction
{ const API_TOKEN = 'https://api.weixin.qq.com/cgi-bin/token';
const API_TICKET = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket';
const TOKEN_EXPIRES = 1500;
const TICKET_EXPIRES = 1500; protected $access_token_key = ''; // access_token Redis 键值名
protected $js_ticket_key = ''; // 凭证 Redis 键值名 public function __construct()
{
parent::__construct();
$this->access_token_key = C('WX_APP_ID').':access_token';
$this->js_ticket_key = C('WX_APP_ID').':js_ticket';
} /**
* 获取全局access_token
*/
public function get()
{
// step1 判是存在
$exists = $this->cacheExists($this->access_token_key); // step2 是否强制刷新或者已过期
if ((isset($_GET['flush']) & $_GET['flush']) || !$exists) {
$data = $this->reload();
} else {
$data = [
'access_token' => $this->getCache($this->access_token_key),
'expires_in' => $this->getCacheTtl($this->access_token_key)
];
} if (!$data['access_token']) {
$this->ajaxReturn($this->jsonError(10002, '接口请求失败'));
} $this->ajaxReturn($this->jsonSuccess(1, '成功', $data));
} /**
* 公众号用于调用微信JS接口的临时票据
* @return bool
*/
public function jsTicket()
{
// step1 判是存在
$exists = $this->cacheExists($this->js_ticket_key);
if (!$exists) {
// 获取token
$token = $this->getCache($this->access_token_key);
setlog($token,[],'token');
// 如果token不存在,重新生成
if (!$token) {
// 重新加载一次Token
$this->reload();
$token = $this->getCache($this->access_token_key);
} $params = [
'access_token' => $token,
'type' => 'jsapi',
]; $data = Http::newDoGet(self::API_TICKET, $params); $data = json_decode($data, true); if ((int)$data['errcode'] !== 0) {
$this->delCache($this->access_token_key);
return false;
} // 减少1500秒过期时间,提前过期
$this->setCache($this->js_ticket_key, $data['ticket'], $data['expires_in'] - self::TICKET_EXPIRES);
} else {
$data['ticket'] = $this->getCache($this->js_ticket_key);
} return $data['ticket'];
} /**
* 获取JS-SDK配置信息
*/
public function getConfig()
{
if (!isset($_GET['uri'])) {
$this->ajaxReturn($this->jsonError(0, '参数错误'));
} $url = $_GET['uri'];
$ticket = $this->jsTicket();
setlog($ticket,[],'ticket'); while (!$ticket) {
$this->reload();
$ticket = $this->jsTicket();
} $data = [
'jsapi_ticket' => $ticket,
'nonceStr' => (string)mt_rand(),
'timestamp' => time(),
'url' => $url
]; $sign = $this->getSign($data); $data['signature'] = $sign;
$data['appId'] = C('WX_APP_ID'); $this->ajaxReturn($this->jsonSuccess(1, '成功', $data));
} /**
* 重新载入 access_token
*/
protected function reload()
{
if ($this->cacheExists($this->access_token_key)) {
$data = [
'access_token' => $this->getCache($this->access_token_key),
'expires_in' => $this->getCacheTtl($this->access_token_key)
];
return $data;
}
$params = [
'grant_type' => 'client_credential',
'appid' => C('WX_APP_ID'),
'secret' => C('WX_APP_SECRET')
];
$data = Http::newDoGet(self::API_TOKEN, $params);
if (!$data) {
$this->ajaxReturn($this->jsonError(10002, '接口请求失败'));
}
$data = json_decode($data, true);
if (isset($data['errcode'])) {
$this->ajaxReturn($this->jsonError($data['errcode']), $data['errmsg']);
}
$this->setCache($this->access_token_key, $data['access_token'], $data['expires_in'] - self::TOKEN_EXPIRES);
return $data;
} /**
* 签名算法
* @param $data
* @return string
*/
protected function getSign($data)
{
$str = '';
foreach ($data as $k => $v) {
$str .= strtolower($k) .'='.$v;
$str .= '&';
} $str = trim($str, '&');
$str = sha1($str); return $str;
} }

微信开发核心AccessToken实现的更多相关文章

  1. 微信开发 获取AccessToken

    获取AccessToken的方法 public static Access_token GetAccessToken() { string formatString = String.Format(& ...

  2. 微信开发笔记(accesstoken)

    access_token分两种 一种是公众号权限获取用,调用cgi-bin接口 ,此种token一个公众号同时只有一个,用这一个就够了. 服务器最好缓存. 用这个token前提是用户关注了此公众号. ...

  3. 使用delphi+intraweb进行微信开发5—准备实现微信API,先从获取AccessToken开始

    在前4讲中我们已经使iw开发的应用成功和微信进行了对接,再接下来的章节中我们开始逐一尝试和实现微信的各个API,开始前先来点准备工作 首先需要明确的是,微信的API都是通过https调用实现的,分为p ...

  4. 微信开发学习日记(八):7步看懂weiphp插件机制,核心目标是响应微信请求

    又经过了几个小时的梳理.回顾,截至目前,终于对weiphp这个框架的机制搞明白了些.想要完全明白,自然还需要大把的时间.第1步:   配置微信公众号,http://weiphp.jiutianniao ...

  5. 微信开发-ACCESS TOKEN 过期失效解决方案

    微信开发-ACCESS TOKEN 过期失效解决方案 起因:因为access_token的重要性,开发过微信的都知道,但是他有自己的生命周期,官方解释为:"有效期为7200秒",一 ...

  6. 微信开发系列----02:实现POST请求响应

    继续昨天的,现在我们的微信测试成功了,可以开发实现微信的各种功能,今天主要实现微信的简单交互,比如发送语音,图片,文本等请求,网站服务器发送对应的响应. 项目GitHub地址:  https://gi ...

  7. 2016北京PHP39期 ThinkPHP Discuz Dedecms 微信开发视频教程

    2016北京PHP39期 ThinkPHP Discuz Dedecms 微信开发视频教程 所有项目均带有软件,笔记,视频,源码 日期   课程(空内容代表放假) 2015/7/10 星期五 开学典礼 ...

  8. 《微信开发日志》之OAuth2验证接口

    OAuth2接口说明: 企业应用中的URL链接(包括自定义菜单或者消息中的链接),可以通过OAuth2.0验证接口来获取员工的身份信息. 通过此接口获取用户身份会有一定的时间开销.对于频繁获取用户身份 ...

  9. html 微信开发——微信授权

    微信JS-SDK说明文档 链接地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html 微信web开发:http: ...

随机推荐

  1. Python逆向(一)—— 前言及Python运行原理

    一.前言 最近在学习Python逆向相关,涉及到python字节码的阅读,编译及反汇编一些问题.经过长时间的学习有了一些眉目,为了方便大家交流,特地将学习过程整理,形成了这篇专题.专题对python逆 ...

  2. Pytest权威教程21-API参考-01-函数(Functions)

    目录 函数(Functions) pytest.approx pytest.fail pytest.skip pytest.importorskip pytest.xfail pytest.exit ...

  3. 模板 - 数据结构 - 栈/Stack

    普通的栈大家都会写,STL的栈据说默认实现方式是deque,没关系反正deque跑得飞快. 这里收录的是一些奇怪的栈,当然双栈实现的队列收录在队列里面. 对顶栈 众所周知,栈可以维护一系列前缀和,包括 ...

  4. Java GUI:将JPanel添加进JScrollPane

    实现的目标: 因为在滚动框中含有很多个Java GUI 组件,因此这里采用JPanel面板包住这些组件,在用JScrollPane实现滚动 问题1:布局揉在一起 JPanel有自己默认的布局方式,因此 ...

  5. 【Vue.js游戏机实战】- Vue.js实现老虎-机抽奖总结

    大家好!先上图看看本次案例的整体效果. 完整版实战课程附源码:[Vue.js游戏机实战]- Vue.js实现老虎-机抽奖 实现思路: Vue component实现老虎-机组件,可以嵌套到任意要使用的 ...

  6. #C++初学记录(贪心算法#二分查找)

    D - Aggressive cows 农夫 John 建造了一座很长的畜栏,它包括N (2 <= N <= 100,000)个隔间,这些小隔间依次编号为x1,...,xN (0 < ...

  7. 信息论 | information theory | 信息度量 | information measures | R代码(一)

    这个时代已经是多学科相互渗透的时代,纯粹的传统学科在没落,新兴的交叉学科在不断兴起. life science neurosciences statistics computer science in ...

  8. MySQL两地三中心方案初步设计【转】

    整体内容会按照如下的方式来进行设计: 首先说下方案的背景,我参考了一些资料(参见附件). 方案背景 随着互联网业务快速发展,多IDC的业务支撑能力和要求也逐步提升,行业内的“两地三中心”方案较为流行. ...

  9. 天池移动推荐算法赛--https://github.com/PnYuan/Tianchi-BigData

    参考: https://blog.csdn.net/Snoopy_Yuan/article/details/75808006

  10. 判断x的m次方和y的m次方末尾三位数是否相等

    /*==============================================对于任意给定的两个正整数x和y,是否存在一个不超过100的正整数m使得x^m与y^m的末尾三位数相等呢? ...