您的位置:首页 > 移动开发 > 微信开发

微信access_token、jsapi_ticket中控服务器

2017-12-10 22:39 429 查看
一:做微信开发的过程中,肯定少不了和access_token打交道
首先要区分 网页授权access_token、基础支持的access_token的不同

a.网页授权access_token 是一次性的,只能获取到一个微信用户信息,是与微信用户一对一的关系,获取次数没有限制。

b.基础支持的access_token的是有时间限制的:7200s,在有效期内就可以使用access_token和openId 获取微信用户信息。

二:如下是微信官方对access_token和jsapi_ticket的描述

1)获取access_token

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。

access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

公众平台的API调用所需的access_token的使用及生成方式说明:

1、建议公众号开发者使用中控服务器统一获取和刷新Access_token,其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务;
2、目前Access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,中控服务器可对外继续输出的老access_token,此时公众平台后台会保证在5分钟内,新老access_token都可用,这保证了第三方业务的平滑过渡;
3、Access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程。


公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在“微信公众平台-开发-基本配置”页中获得(需要已经成为开发者,且帐号没有异常状态)。调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功。

2)jsapi_ticket

生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket


1.参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):../15/54ce45d8d30b6bf6758f68d2e95bc627.html

2.用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

三:access_token中控器

access_token每天有使用次数限制,所以客户服务器不能每次是都去请求一个新的access_token,每次请求之后,access_token都有一个过期时间。因此微信平台建议你使用一个中控服务器来定时刷新token,取得之后存起来不用再去请求token,因为access_token请求有次数限制。
这样处理只有有两个好处:
保证access_token每日都不会超出访问限制,保证服务的正常。
提高服务的性能,不用每次发送业务请求之前都先发送一次access_token获取请求。
将access_token保存在内存中这种模式效率最高,但无法支持集群模式,对后续系统扩容影响较大,所以推荐存放在redis、传统数据库中。


1)注册监听器

public class TokenListener implements ServletContextListener{

private static Logger log = Logger.getLogger(TokenListener.class);

private Timer timer = null;

@Override
public void contextInitialized(ServletContextEvent arg0) {
log.info("accessToken监听器启动..........");
timer = new Timer(true);//Timer是调度控制器,TimerTask是可调度的任务
//注册定时任务
registeAccessTokenTimer();
//注册jsapi_ticket定时器
registeJsApiTicketTimer();
}

@Override
public void contextDestroyed(ServletContextEvent arg0) {
timer.cancel();
}

/**
* 注册accessToken定时器
*/
private void registeAccessTokenTimer(){
AccessTokenTimer accessTokenTimer = new AccessTokenTimer();
timer.schedule(accessTokenTimer, AccessTokenTimer.DELAY,AccessTokenTimer.PERIOD);
log.info("accessToken定时器注册成功,执行间隔为" + AccessTokenTimer.PERIOD);
}

/**
* 注册jsapi_ticket定时器
*/
private void registeJsApiTicketTimer(){
JsApiTicketTimer jsApiTicketTimer = new JsApiTicketTimer();
timer.schedule(jsApiTicketTimer, JsApiTicketTimer.DELAY,JsApiTicketTimer.PERIOD);
log.info("jsapi_ticket定时器注册成功,执行间隔为" + JsApiTicketTimer.PERIOD);
}

}

2)定时器,7000s刷新一下

public class AccessTokenTimer extends TimerTask{

private static Logger logger = Logger.getLogger(AccessTokenTimer.class);

//accessToken有效期7200秒,提前200秒请求新的token
public static final long PERIOD = 7000 * 1000;
public static final long DELAY = 0; //此任务的延迟时间为0,即立即执行

@Override
public void run() {
logger.info("accessToken 定时任务启动,获取新的accessToken");
//得到新的access token
AccessToken accessToken = new AccessToken();
//获取成功之后持久化accessToken
if(accessToken.request()){
AccessTokenServer accessTokenServer = new AccessTokenServer();
CustomerServer customerServer = (CustomerServer)accessTokenServer.customerServer();
customerServer.save(accessToken);
}
}

}

3)保存到数据库

public class CustomerAccessTokenServer extends CustomerServer {

private BaseDaoImpl baseDaoImpl = SpringContextHolder.getBean("baseDaoImpl");;

protected String query() {
String accessToken = null;
// 执行数据库操作
String sql = "select cfgValue from x_cfg where cfgKey = 'access_token'";
List<Map<String, Object>> list = (List<Map<String, Object>>) baseDaoImpl.queryBySql(sql);
if (list != null && list.size() > 0) {
accessToken = list.get(0).get("cfgValue").toString();
}
return accessToken;
}

public boolean save(Token token) {
String sql0 = "select count(id) countNum from x_cfg where cfgKey = 'access_token'";
String sql = "";
List<Map<String, Long>> list = (List<Map<String, Long>>) baseDaoImpl.queryBySql(sql0);
if (list != null && list.size() > 0 && list.get(0).get("countNum") > 0) {
sql = "update x_cfg set cfgValue='" + token.getToken() + "',update_time=NOW() where cfgKey= 'access_token'";
} else {
sql = "insert into x_cfg(cfgKey,cfgValue,create_time,comments) values('access_token','" + token.getToken() + "',NOW(),'access_token')";
}
try {
baseDaoImpl.executeSQL(sql);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}

}

4)启动后
2017-12-09 23:29:52,796 INFO [com.xyx.test.TokenListener] - <accessToken监听器启动..........>
2017-12-09 23:29:52,796 INFO [com.xyx.test.TokenListener] - <accessToken定时器注册成功,执行间隔为7000000>
2017-12-09 23:29:52,796 INFO [com.xyx.test.timer.AccessTokenTimer] - <accessToken 定时任务启动,获取新的accessToken>
2017-12-09 23:29:52,796 INFO [com.xyx.test.AccessToken] - <创建获取access_token url>
2017-12-09 23:29:52,796 INFO [com.xyx.test.TokenListener] - <jsapi_ticket定时器注册成功,执行间隔为7000000>
2017-12-09 23:29:53,688 INFO [com.xyx.test.token.Token] - <token获取成功>
2017-12-09 23:29:53,688 INFO [com.xyx.dao.impl.BaseDaoImpl] - <select count(id) countNum from x_cfg where cfgKey = 'access_token'>
2017-12-09 23:29:53,688 INFO [com.xyx.dao.impl.BaseDaoImpl] - <update x_cfg set cfgValue='sMehtw5OqyiWpHustpghL2Yca2nnIjtCAq-LfILVJE4PTB0RjcMSwuvLmaiM_9fpwZyFPj7taoT5PsKLW0TRZ_PDoW0tQe-4iz9hX2EjrXkas15mP4El1NqTVMXFOiFkYHFhAHAHQO',update_time=NOW() where cfgKey= 'access_token'>
2017-12-09 23:29:53,736 INFO [com.xyx.test.timer.JsApiTicketTimer] - <jsapi_ticket 定时任务启动,获取新的jsapi_ticket>
2017-12-09 23:29:53,736 INFO [com.xyx.dao.impl.BaseDaoImpl] - <select cfgValue from x_cfg where cfgKey = 'access_token'>
2017-12-09 23:29:53,736 INFO [com.xyx.test.Ticket] - <获取ticket,ticket类型jsapi>
2017-12-09 23:29:53,814 INFO [com.xyx.test.Token] - <token获取成功>
2017-12-09 23:29:53,814 INFO [com.xyx.dao.impl.BaseDaoImpl] - <select count(id) countNum from x_cfg where cfgKey = 'jsapi_ticket'>
2017-12-09 23:29:53,814 INFO [com.xyx.dao.impl.BaseDaoImpl] - <update x_cfg set cfgValue='kgt8ON7yVITDhtdwci0qeebpwqL128T4V12pYceoCl1yb4uzi6lbn7UNivbmdNBfJ85iU1V_318zr1HlKkF78w',update_time=NOW() where cfgKey= 'jsapi_ticket'>











                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息