官方文档介绍:https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Login/Development_Guide.html
代码:
WXTokenEntity 对应 通过code 获取 access token
public class WXTokenEntity {
//请求访问token
private String accessToken;
//刷新token
private String refreshToken;
//accessToken 过期时间戳 = System.currentTimeMillis() + expire_in
private Long expiresTimestamp;
//用户对外ID
private String openid;
//访问范围
private String scope;
//联合ID openid只是用户在某一应用下的唯一标识,多个应用的unionid相同
private String unionid;
private Long refreshTokenExpiresTimestamp;
public WXTokenEntity() {
}
public WXTokenEntity(String accessToken, String refreshToken, Long expiresTimestamp, String openid, String scope, String unionid,Long refreshTokenExpiresTimestamp) {
this.accessToken = accessToken;
this.refreshToken = refreshToken;
this.expiresTimestamp = expiresTimestamp;
this.openid = openid;
this.scope = scope;
this.unionid = unionid;
this.refreshTokenExpiresTimestamp = refreshTokenExpiresTimestamp;
}
。。。省略setter getter方法。。。
}
http请求获取信息 包括 access token 获取,userInfo 获取,refresh token,需要依赖 fastJson 和 apache http 组件
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
public class WXAuthUtils {
private static final String APP_ID = "你自己的APPID";
private static final String APP_secret = "你自己的APPsecret";
private static final String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?grant_type=authorization_code&appid=%s&secret=%s&code=%s";
private static final String TOKEN_IS_VALID_URL = "https://api.weixin.qq.com/sns/auth?access_token=%s&openid=%s";
private static final String USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s";
private static final String REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s";
private static final int SUCCESS_CODE = 200;
private static final int ONE_MONTH = 1000*60*60*24*30;
/**
* 获取AccessToken
*/
public static WXTokenEntity getAccessToken(String code) {
if(StringUtils.isBlank(code)){
return null;
}
//生成url
String url = String.format(GET_ACCESS_TOKEN_URL, APP_ID, APP_secret, code);
try {
HttpResponse response = executeGetHttp(url);
ResponseWrapper responseWrapper = ResponseWrapper.of(response);
return responseWrapper.buildWXTokenEntity();
} catch (Exception e) {
e.printStackTrace();
// throw new RuntimeException("wx catch access token error...");
}
return null;
}
/**
* 获取用户信息
*/
public static JSONObject getUserInfo(WXTokenEntity wxTokenEntity) {
if(null == wxTokenEntity){
return null;
}
//TODO 如果过期 是否使用refresh token刷新,一般来说基本上都是立马使用,不会存在过期问题,除非你的业务有特殊操作
if (isAccessTokenIsInvalid(wxTokenEntity) && System.currentTimeMillis() < wxTokenEntity.getExpiresTimestamp()) {
//url 生成
String url = String.format(USER_INFO_URL, wxTokenEntity.getAccessToken(), wxTokenEntity.getOpenid());
try {
HttpResponse response = executeGetHttp(url);
ResponseWrapper responseWrapper = ResponseWrapper.of(response);
return responseWrapper.getJSONObject();
} catch (Exception e) {
e.printStackTrace();
// throw new RuntimeException(" wx catch user info error...");
}
}
return null;
}
private static boolean isAccessTokenIsInvalid(WXTokenEntity wxTokenEntity) {
if(null == wxTokenEntity
|| StringUtils.isBlank(wxTokenEntity.getOpenid())
|| StringUtils.isBlank(wxTokenEntity.getAccessToken())){
return false;
}
//url 生成
String url = String.format(TOKEN_IS_VALID_URL, wxTokenEntity.getAccessToken(), wxTokenEntity.getOpenid());
try {
HttpResponse response = executeGetHttp(url);
return ResponseWrapper.of(response).isVisitSuccess;
} catch (Exception e) {
e.printStackTrace();
// throw new RuntimeException("wx isAccessTokenIsInvalid error...");
}
return false;
}
public static WXTokenEntity refreshAccessToken(String oldRefreshToken) {
if (StringUtils.isBlank(oldRefreshToken)) {
return null;
}
//url 生成
String url = String.format(REFRESH_TOKEN_URL, APP_ID, oldRefreshToken);
try {
HttpResponse response = executeGetHttp(url);
return ResponseWrapper
.of(response)
.buildWXTokenEntity();
} catch (Exception e) {
e.printStackTrace();
// throw new RuntimeException("wx refreshAccessToken error...");
}
return null;
}
public static HttpResponse executeGetHttp(String url) throws Exception {
URI uri = URI.create(url);
HttpClient client = new DefaultHttpClient();
return client.execute(new HttpGet(uri));
}
private static boolean responseIsSuccess(HttpResponse response) {
return response.getStatusLine().getStatusCode() == SUCCESS_CODE;
}
static class ResponseWrapper{
private HttpResponse response;
private boolean responseIsSuccess = false;
private boolean isVisitSuccess = false;
private JSONObject jsonObject = null;
public static ResponseWrapper of(HttpResponse response) throws Exception {
return new ResponseWrapper(response);
}
public ResponseWrapper(HttpResponse response) throws Exception {
this.response = response;
this.responseIsSuccess = response.getStatusLine().getStatusCode() == SUCCESS_CODE;
if(this.responseIsSuccess){
jsonObject = parseResponse2JsonObject();
this.isVisitSuccess = isVisitSuccess(jsonObject);
}
}
public JSONObject getJSONObject(){
if(!this.responseIsSuccess){
throw new RuntimeException("response error");
}
return this.jsonObject;
}
private WXTokenEntity buildWXTokenEntity() throws IOException {
if(!this.responseIsSuccess){
throw new RuntimeException("response error");
}
if(!this.isVisitSuccess){
throw new RuntimeException(jsonObject.getString("errormsg"));
}
return buildWXTokenEntity(jsonObject);
}
private boolean responseIsSuccess() {
return this.responseIsSuccess;
}
private boolean isVisitSuccess(JSONObject jsonObject) {
if(null == jsonObject){
throw new RuntimeException("wx jsonObject must be not null...");
}
Integer errorCode = jsonObject.getInteger("errcode");
if (null == errorCode || errorCode.intValue() == 0) {
return true;
}
return false;
}
private JSONObject parseResponse2JsonObject() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
sb.append(temp);
}
//返回JSONObject 包装
JSONObject jsonObject = JSONObject.parseObject(sb.toString().trim());
return jsonObject;
}
private WXTokenEntity buildWXTokenEntity(JSONObject jsonObject) {
String accessToken = jsonObject.getString("access_token");
String openID = jsonObject.getString("openid");
String refreshToken = jsonObject.getString("refresh_token");
Long expires_in = jsonObject.getLong("expires_in");
String scope = jsonObject.getString("scope");
//refresh token 的时候并没有该参数
String unionid = jsonObject.getString("unionid");
//计算出过期时间戳
Long expiresTimestamp = System.currentTimeMillis() + expires_in * 1000;
// Long expires_in = jsonObject.getLong("expiresTimestamp");
//计算出过期时间戳 这里调试过后,好像 refreshToken 不会变化,但是过期时间不确定是否会被延长
Long refreshTokenExpiresTimestamp = System.currentTimeMillis() + ONE_MONTH;
return new WXTokenEntity(accessToken, refreshToken, expiresTimestamp, openID, scope, unionid,refreshTokenExpiresTimestamp);
}
}
} 单元测试类
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.junit.Test;
public class WXAuthUtilsTest {
@Test
public void testUserInfoBeginWithCode() {
String code = "xxxxxxxxxxxxxxxx";
WXTokenEntity wxTokenEntity = WXAuthUtils.getAccessToken(code);
System.out.println("accessToken : " + JSON.toJSONString(wxTokenEntity));
JSONObject userInfo = WXAuthUtils.getUserInfo(wxTokenEntity);
System.out.println("userInfo : " + userInfo.toJSONString());
}
@Test
public void testGetAccessToken() {
String code = "xxxxxxxxxxxxxxxx";
WXTokenEntity wxTokenEntity = WXAuthUtils.getAccessToken(code);
System.out.println("accessToken : " + JSONObject.toJSONString(wxTokenEntity));
}
@Test
public void testGetUserInfoSuccess() {
String accessToken = "xxxxxxxxxxxxxxxx-aYSD52-R6h73Ngi2kmmWuSxXfSd-jBXwKTqx1qODh3x_3WW_r_L_UrK0";
String openid = "o-xxxxxxxxxxxxxxxx-pqkPcCQxK43fxQ";
Long expiresTimestamp = System.currentTimeMillis() + 7200;
WXTokenEntity wxTokenEntity = new WXTokenEntity(accessToken, null, expiresTimestamp, openid, null, null,null);
JSONObject userInfo = WXAuthUtils.getUserInfo(wxTokenEntity);
System.out.println("用户信息 : " + userInfo.toJSONString());
}
@Test
public void testRefreshToken() {
String refreshToken = "xxxxxxxxxxxxxxxx-DtycJk_mTl_Uuz8dp409L5U";
Long expiresTimestamp = System.currentTimeMillis() + 7200;
WXTokenEntity wxTokenEntity = WXAuthUtils.refreshAccessToken(refreshToken);
System.out.println("用户信息 : " + JSON.toJSONString(wxTokenEntity));
}
@Test
public void testGetUserInfoFailureMissingOpenid() {
String accessToken = "xxxxxxxxxxxxxxxx-Y_PeAgo0SUciGRlKE0I8bX4A-nviz9N-gnj10FZtlaB62bEgrb1vrmqNOQqh8OYWUvTZ9GM";
String openid = "ee";
Long expiresTimestamp = System.currentTimeMillis() + 7200;
WXTokenEntity wxTokenEntity = new WXTokenEntity(accessToken, null, expiresTimestamp, openid, null, null,null);
JSONObject userInfo = WXAuthUtils.getUserInfo(wxTokenEntity);
System.out.println("用户信息 : " + userInfo.toJSONString());
}
} 业务肯定没问题,只是看里面一些地方是否符合你们自身业务使用。
本文标题:APP调用微信三方登陆 授权码模式 工具代码
本文链接:https://blog.quwenai.cn/post/2868.html
版权声明:本文不使用任何协议授权,您可以任何形式自由转载或使用。




![[并发编程] - Executor框架#ThreadPoolExecutor源码解读02 [并发编程] - Executor框架#ThreadPoolExecutor源码解读02](https://blog.quwenai.cn/zb_users/upload/2022/03/20220327124158164835611866353.png)

还没有评论,来说两句吧...