access_token是何物,access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
官方是这么介绍的,由于有请求次数限制,肯定不能随用随取,需要采用中控服务器保存。
此外在刷新过程中,中控服务器可对外继续输出的老access_token,此时公众平台后台会保证在5分钟内,新老access_token都可用,这保证了第三方业务的平滑过渡,这就保证了不需要考虑access_token失效的问题了,前提是正确获取到并及时刷新了。
一、安装Redis
Linux可以用docker去安装,Windows下安装并设置Redis
二、获取access_token并缓存到Redis
AppID和AppSecret可在“微信公众平台-开发-基本配置”页中获得(需要已经成为开发者,且帐号没有异常状态)。
如果是测试号,不存在白名单一说,正式的公众号调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功
声明: 由于没开发过实际的公众号,不清楚如何正确的缓存access_token,只是我个人的做法。
多环境配置,在application-dev.yml加入 ,appid 、appsecret、token替换成自己的
#wechat
wechat:
appid: yours
appsecret: yours
token: yours
读取配置
/** * FileName: WechatAccountConfig * Author: Phil * Date: 11/20/2018 3:10 PM * Description: 配置文件 * History: * <author> <time> <version> <desc> * 作者姓名 修改时间 版本号 描述 */ package com.phil.modules.config; import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * 〈一句话功能简述〉<br> * 〈接入配置信息〉 * * @author Phil * @create 11/20/2018 3:10 PM * @since 1.0 */ @Component @Getter @Setter @ConfigurationProperties(prefix = "wechat") public class WechatAccountConfig { /*** * 微信的appid */ private String appid; /*** * 微信的secret */ private String appsecret; /*** * 微信授权url */ private String returnUrl; /*** * 微信的验证token */ private String token; }
application.properties里加上配置
#auth
#获取凭证的链接
wechat.auth.get-access-token-url=https://api.weixin.qq.com/cgi-bin/token
读取配置
/** * FileName: WechatAuthConfig * Author: Phil * Date: 11/21/2018 7:10 PM * Description: * History: * <author> <time> <version> <desc> * 作者姓名 修改时间 版本号 描述 */ package com.phil.wechat.auth.config; import lombok.Getter; import lombok.Setter; import lombok.ToString; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * 〈一句话功能简述〉<br> * 〈〉 * * @author Phil * @create 11/21/2018 7:10 PM * @since 1.0 */ @Component @Getter @Setter @ToString @ConfigurationProperties(prefix = "wechat.auth") public class WechatAuthConfig { //获取凭证 private String getAccessTokenUrl; }
定义接收的实体Bean
/**
* FileName: AccessToken
* Author: Phil
* Date: 12/4/2018 2:13 PM
* Description:
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 描述
*/
package com.phil.wechat.auth.model.response;
import com.google.gson.annotations.SerializedName;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* 〈一句话功能简述〉<br>
* 〈微信通用接口凭证〉
*
* @author Phil
* @create 12/4/2018 2:13 PM
* @since 1.0
*/
@Getter
@Setter
public class AccessToken implements Serializable {
private static final long serialVersionUID = 5806078615354556552L;
// 获取到的凭证
@SerializedName("access_token")
private String accessToken;
// 凭证有效时间,单位:秒
private int expires_in;
}
读取并缓存到Redis
/** * FileName: AuthServiceImpl * Author: Phil * Date: 11/21/2018 12:13 PM * Description: * History: * <author> <time> <version> <desc> * 作者姓名 修改时间 版本号 描述 */ package com.phil.wechat.auth.service.impl; import com.google.gson.JsonSyntaxException; import com.phil.modules.config.WechatAccountConfig; import com.phil.modules.result.ResultState; import com.phil.modules.util.HttpUtil; import com.phil.modules.util.JsonUtil; import com.phil.modules.util.RedisUtils; import com.phil.wechat.auth.config.WechatAuthConfig; import com.phil.wechat.auth.model.BasicAuthParam; import com.phil.wechat.auth.model.response.AccessToken; import com.phil.wechat.auth.model.response.AuthAccessToken; import com.phil.wechat.auth.model.response.AuthUserInfo; import com.phil.wechat.auth.service.WechatAuthService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.TreeMap; /** * 〈一句话功能简述〉<br> * 〈〉 * * @author Phil * @create 11/21/2018 12:13 PM * @since 1.0 */ @Service @Slf4j public class WechatAuthServiceImpl implements WechatAuthService { @Value("${wechat.token}") private String token; @Resource RedisUtils redisUtils; @Resource WechatAuthConfig wechatAuthConfig; @Resource private WechatAccountConfig wechatAccountConfig; /** * 获取授权凭证token * * @return 授权凭证token */ @Override public String getAccessToken() { String accessToken = null; if (Objects.isNull(redisUtils.get(token))) { Map<String, String> map = new TreeMap<>(); map.put("appid", wechatAccountConfig.getAppid()); map.put("secret", wechatAccountConfig.getAppsecret()); map.put("grant_type", "client_credential"); String json = HttpUtil.doGet(wechatAuthConfig.getGetAccessTokenUrl(), map); AccessToken bean = JsonUtil.fromJson(json, AccessToken.class); if (bean != null) { accessToken = bean.getAccessToken(); log.info("从微信服务器获取的授权凭证{}", accessToken); redisUtils.set(token, accessToken, 60 * 120); log.info("从微信服务器获取的token缓存到Redis"); } } else { accessToken = redisUtils.get(token).toString(); log.info("从redis中获取的授权凭证{}", accessToken); } return accessToken; } }
又或者可以使用定时去缓存刷新
完整代码查看GitHub链接,不定时更新