文档章节

微信公众号开发教程02:获取access_token

kolbe
 kolbe
发布于 2016/04/20 17:31
字数 839
阅读 721
收藏 10

一、access_token简介

access_token是公众号接口调用的凭据,公众号调用各接口时均需使用access_token。

例如:

1)创建自定义菜单接口:https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN

2)获取素材列表接口:https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN

3)获取用户基本信息接口:https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

等等,这些接口的请求地址均需要一个ACCESS_TOKEN参数,该参数就需要调用获取access_token接口来获取

注意:

1)access_token有时效性,当前有效时间为7200秒,需要的存储空间为512个字符空间,需要注意的是,微信后期有可能会改这个access_token的过期时间

2)如果在布署中有多台业务逻辑服务器均在自己的程序中获取access_token,这将造成多次刷新access_token的情况,建议布署中通过一台中控服务器来统一获取,或者将access_token存入缓存中统一读取


二、access_token获取方式

1、接口请求地址:

http请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

2、请求参数说明:

参数 是否必须 说明
grant_type 获取access_token固定为client_credential
appid 第三方用户唯一任证
secret 第三方用户唯一任证密钥

注:appid和secret对应的是公众平台后台中,【开发】选项中的【基本配置】中AppID和AppSecret

3、返回说明:

1)成功

{"access_token":"ACCESS_TOKEN","expires_in":7200}

2)失败

{"errcode":40013,"errmsg":"invalid appid"}


三、access_token获取代码实现

下面是access_token获取的java实现,注该代码中json解析使用到了阿里巴巴的fastjson

package cn.kolbe.wechat.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * 获取微信accessToken
 * @author admin
 *
 */
public class AccessTokenUtil {
	
	private static final String APP_ID = "xxxxxxx";
	private static final String APP_SECRET = "xxxxxx";
	// 当前程序使用的accessToken
	private static String accessToken = "";
	// 微信获取accessToken的接口地址
	private static final String GET_ACCESS_TOKEN_API = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APP_ID + "&secret=" + APP_SECRET;
	// accessToken的过期时效
	private static final int EXPIRED_SECONDS = 7200;
	// 当前最后更新accessToken的日期
	private static Date latestDate = new Date();
	
	/**
	 * 获取accessToken
	 * @return
	 */
	public static String getToken() {
		Date now = new Date();
		if((now.getTime() - latestDate.getTime()) < EXPIRED_SECONDS*1000 && !accessToken.equals("")) {
			System.out.println("已经存在accessToken," + accessToken);
			return accessToken;
		} else {
			// 防止并发环境下,重复更新accessToken
			synchronized(AccessTokenUtil.class) {
				if((now.getTime() - latestDate.getTime()) < EXPIRED_SECONDS*1000 && !accessToken.equals("")) {
					System.out.println("accessToken已经被更新过," + accessToken);
					return accessToken;
				}
				System.out.println("accessToken过期,重新生成," + accessToken);
				latestDate = new Date();
				JSONObject json = JSON.parseObject(sendGet(GET_ACCESS_TOKEN_API));
				accessToken = json.getString("access_token");
				return accessToken;
			}
		}
	}
	
	
	/**
	 * 简易发送Http的Get请求
	 * @param urlStr
	 * @return
	 */
	private static String sendGet(String urlStr) {
		URL url = null;
		URLConnection conn = null;
		BufferedReader reader = null;
		try {
			url = new URL(urlStr);
			conn = url.openConnection();
			conn.connect();
			reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));
			StringBuilder result = new StringBuilder();
			String s = new String();
			while((s = reader.readLine()) != null) {
				result.append(s);
			}
			return result.toString();
		} catch(Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 测试并发环境下,获取accessToken
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		ExecutorService executor = Executors.newCachedThreadPool();
		for(int i = 0; i < 100; i++) {
			if(i % 10 == 0) {
				Thread.sleep(1000);
			}
			executor.submit(new AccessTokenUtil.AccessTokenThread());
		}
	}
	
	/**
	 * 模拟并发环境下,获取accessToken
	 * @author admin
	 *
	 */
	public static class AccessTokenThread implements Runnable {

		@Override
		public void run() {
			AccessTokenUtil.getToken();
		}
		
	}
	
}


注:

1)该代码中并没有考虑错误情况下的处理方式(建议提供一个强制刷新accessToken的方法)

2)刷新accessToken时,需要注意考虑并发情况下,同时多个线程发现accessToken过期,重复去刷新accessToken的情况,代码中已经通过加锁来防止这种情况的发生








© 著作权归作者所有

kolbe
粉丝 118
博文 20
码字总数 21363
作品 0
成都
程序员
私信 提问
基于Koa.js的微信工具类小记

关于微信公众号开发和小程序开发的教程其实网上已经有很多了,但是基于koa.js 开发的教程其实不多,于是接下来对踩坑的经历做一些小结; 自己也写了一个微信工具类,项目地址是微信工具类 ...

evont
07/09
0
0
bfbd/wechat-proxy

wechat-proxy (微信代理服务) 全局缓存微信 access_token, jsapi ticket等。 多路转发微信回调消息。 简化微信 oauth2 认证流程。 简化微信支付流程。 简化微信 JSSDK 签名流程。 示例 注册a...

bfbd
2017/10/02
0
0
微信程序开发系列教程(三)使用微信API给微信用户发文本消息

这个系列的第二篇教程,介绍的实际是被动方式给微信用户发文本消息,即微信用户关注您的公众号时,微信平台将这个关注事件通过一个HTTP post发送到您的微信消息服务器上。您对这个post请求做...

jerrywangsap
08/26
0
0
微信第三方活动 关注微信公众号才能参与

#产品要求:必须先关注公众号才能参与活动 ###上面需求涉及到的几个点: 1.access_token中继服务 2.第三方页面授权 3.获取微信用户信息 前面有一篇 node.js定时获取accesstoken 那么根据此博文...

一介布衣
2016/08/18
0
0
node.js 微信开发 提交菜单

前面连续分享2篇关于微信开发的文章. node.js 定时获取 access_token 使用 wechat 开发微信回调接口 今天分享 node.js 开发微信菜单 前提: 1.首先是切换到了开发者模式 2.微信管理后台已经授...

一介布衣
2016/08/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Confluence 6 配置边栏

如果你具有空间的管理员权限,你可以对空间的变量进行自定义,让你的空间具有自己的空间标识(logo),修改显示的继承关系和在空间中添加快捷方式以帮助用户在空间中进行快速导航。 希望开始...

honeymose
5分钟前
0
0
Ubuntu18.04 安装MySQL

1.安装MySQL sudo apt-get install mysql-server 2.配置MySQL sudo mysql_secure_installation 3.设置MySQL非root用户 设置原因:配置过程为系统root权限,在构建MySQL连接时出现错误:ERROR...

AI_SKI
今天
3
0
3.6 rc脚本(start方法) 3.7 rc脚本(stop和status方法) 3.8 rc脚本(以daemon方式启动)

3.6-3.7 rc脚本(start、stop和status方法) #!/usr/bin/env python# -*- coding: utf-8 -*-# [@Version](https://my.oschina.net/u/931210) : python 2.7# [@Time](https://my.oschina.......

隐匿的蚂蚁
今天
3
0
Cnn学习相关博客

CNN卷积神经网络原理讲解+图片识别应用(附源码) 笨方法学习CNN图像识别系列 深度学习图像识别项目(中):Keras和卷积神经网络(CNN) 卷积神经网络模型部署到移动设备 使用CNN神经网络进行...

-九天-
昨天
5
0
flutter 底部输入框 聊天输入框 Flexible

想在页面底部放个输入框,结果键盘一直遮住了,原来是布局问题 Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("评论"), ...

大灰狼wow
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部