提交 4d2518e2 编写于 作者: 不合群的混子's avatar 不合群的混子

集成微信公众号登录,修改之前的微信登录为微信开放平台登录

上级 264294ca
......@@ -79,7 +79,7 @@ String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
```java
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.request.AuthWeChatRequest;
import me.zhyd.oauth.request.AuthWeChatOpenRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.web.bind.annotation.PathVariable;
......@@ -107,7 +107,7 @@ public class RestAuthController {
}
private AuthRequest getAuthRequest() {
return new AuthWeChatRequest(AuthConfig.builder()
return new AuthWeChatOpenRequest(AuthConfig.builder()
.clientId("Client ID")
.clientSecret("Client Secret")
.redirectUri("https://www.zhyd.me/oauth/callback/wechat")
......
......@@ -6,7 +6,7 @@
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.13.1</version>
<version>1.13.2-SNAPSHOT</version>
<name>JustAuth</name>
<url>https://gitee.com/yadong.zhang/JustAuth</url>
......
......@@ -240,9 +240,9 @@ public enum AuthDefaultSource implements AuthSource {
}
},
/**
* 微信
* 微信开放平台
*/
WECHAT {
WECHAT_OPEN {
@Override
public String authorize() {
return "https://open.weixin.qq.com/connect/qrconnect";
......@@ -263,6 +263,30 @@ public enum AuthDefaultSource implements AuthSource {
return "https://api.weixin.qq.com/sns/oauth2/refresh_token";
}
},
/**
* 微信公众平台
*/
WECHAT_MP {
@Override
public String authorize() {
return "https://open.weixin.qq.com/connect/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://api.weixin.qq.com/sns/oauth2/access_token";
}
@Override
public String userInfo() {
return "https://api.weixin.qq.com/sns/userinfo";
}
@Override
public String refresh() {
return "https://api.weixin.qq.com/sns/oauth2/refresh_token";
}
},
/**
* 淘宝
*/
......
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.GlobalAuthUtil;
import me.zhyd.oauth.utils.UrlBuilder;
/**
* 微信公众平台登录
*
* @author yangkai.shen (https://xkcoding.com)
* @since 1.1.0
*/
public class AuthWeChatMpRequest extends AuthDefaultRequest {
public AuthWeChatMpRequest(AuthConfig config) {
super(config, AuthDefaultSource.WECHAT_MP);
}
public AuthWeChatMpRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthDefaultSource.WECHAT_MP, authStateCache);
}
/**
* 微信的特殊性,此时返回的信息同时包含 openid 和 access_token
*
* @param authCallback 回调返回的参数
* @return 所有信息
*/
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
return this.getToken(accessTokenUrl(authCallback.getCode()));
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
String openId = authToken.getOpenId();
HttpResponse response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response.body());
this.checkResponse(object);
String location = String.format("%s-%s-%s", object.getString("country"), object.getString("province"), object.getString("city"));
if (object.containsKey("unionid")) {
authToken.setUnionId(object.getString("unionid"));
}
AuthUserGender sex;
switch (object.getString("sex")) {
case "1":
sex = AuthUserGender.MALE;
break;
case "2":
sex = AuthUserGender.FEMALE;
break;
default:
sex = AuthUserGender.UNKNOWN;
}
return AuthUser.builder()
.username(object.getString("nickname"))
.nickname(object.getString("nickname"))
.avatar(object.getString("headimgurl"))
.location(location)
.uuid(openId)
.gender(sex)
.token(authToken)
.source(source.toString())
.build();
}
@Override
public AuthResponse refresh(AuthToken oldToken) {
return AuthResponse.builder()
.code(AuthResponseStatus.SUCCESS.getCode())
.data(this.getToken(refreshTokenUrl(oldToken.getRefreshToken())))
.build();
}
/**
* 检查响应内容是否正确
*
* @param object 请求响应内容
*/
private void checkResponse(JSONObject object) {
if (object.containsKey("errcode")) {
throw new AuthException(object.getIntValue("errcode"), object.getString("errmsg"));
}
}
/**
* 获取token,适用于获取access_token和刷新token
*
* @param accessTokenUrl 实际请求token的地址
* @return token对象
*/
private AuthToken getToken(String accessTokenUrl) {
HttpResponse response = HttpRequest.get(accessTokenUrl).execute();
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
this.checkResponse(accessTokenObject);
return AuthToken.builder()
.accessToken(accessTokenObject.getString("access_token"))
.refreshToken(accessTokenObject.getString("refresh_token"))
.expireIn(accessTokenObject.getIntValue("expires_in"))
.openId(accessTokenObject.getString("openid"))
.scope(accessTokenObject.getString("scope"))
.build();
}
/**
* 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
*
* @param state state 验证授权流程的参数,可以防止csrf
* @return 返回授权地址
* @since 1.9.3
*/
@Override
public String authorize(String state) {
return UrlBuilder.fromBaseUrl(source.authorize())
.queryParam("appid", config.getClientId())
.queryParam("redirect_uri", GlobalAuthUtil.urlEncode(config.getRedirectUri()))
.queryParam("response_type", "code")
.queryParam("scope", "snsapi_userinfo")
.queryParam("state", getRealState(state).concat("#wechat_redirect"))
.build();
}
/**
* 返回获取accessToken的url
*
* @param code 授权码
* @return 返回获取accessToken的url
*/
@Override
protected String accessTokenUrl(String code) {
return UrlBuilder.fromBaseUrl(source.accessToken())
.queryParam("appid", config.getClientId())
.queryParam("secret", config.getClientSecret())
.queryParam("code", code)
.queryParam("grant_type", "authorization_code")
.build();
}
/**
* 返回获取userInfo的url
*
* @param authToken 用户授权后的token
* @return 返回获取userInfo的url
*/
@Override
protected String userInfoUrl(AuthToken authToken) {
return UrlBuilder.fromBaseUrl(source.userInfo())
.queryParam("access_token", authToken.getAccessToken())
.queryParam("openid", authToken.getOpenId())
.queryParam("lang", "zh_CN")
.build();
}
/**
* 返回获取userInfo的url
*
* @param refreshToken getAccessToken方法返回的refreshToken
* @return 返回获取userInfo的url
*/
@Override
protected String refreshTokenUrl(String refreshToken) {
return UrlBuilder.fromBaseUrl(source.refresh())
.queryParam("appid", config.getClientId())
.queryParam("grant_type", "refresh_token")
.queryParam("refresh_token", refreshToken)
.build();
}
}
......@@ -16,18 +16,18 @@ import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.UrlBuilder;
/**
* 微信登录
* 微信开放平台登录
*
* @author yangkai.shen (https://xkcoding.com)
* @since 1.1.0
*/
public class AuthWeChatRequest extends AuthDefaultRequest {
public AuthWeChatRequest(AuthConfig config) {
super(config, AuthDefaultSource.WECHAT);
public class AuthWeChatOpenRequest extends AuthDefaultRequest {
public AuthWeChatOpenRequest(AuthConfig config) {
super(config, AuthDefaultSource.WECHAT_OPEN);
}
public AuthWeChatRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthDefaultSource.WECHAT, authStateCache);
public AuthWeChatOpenRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthDefaultSource.WECHAT_OPEN, authStateCache);
}
/**
......
......@@ -2,7 +2,7 @@ package me.zhyd.oauth.utils;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.request.AuthWeChatRequest;
import me.zhyd.oauth.request.AuthWeChatOpenRequest;
import org.junit.Assert;
import org.junit.Test;
......@@ -22,7 +22,7 @@ public class UrlBuilderTest {
.clientSecret("secret-110110110")
.redirectUri("https://xkcoding.com")
.build();
String build = UrlBuilder.fromBaseUrl(AuthDefaultSource.WECHAT.authorize())
String build = UrlBuilder.fromBaseUrl(AuthDefaultSource.WECHAT_OPEN.authorize())
.queryParam("appid", config.getClientId())
.queryParam("redirect_uri", config.getRedirectUri())
.queryParam("response_type", "code")
......@@ -30,7 +30,7 @@ public class UrlBuilderTest {
.queryParam("state", "")
.build(false);
System.out.println(build);
AuthWeChatRequest request = new AuthWeChatRequest(config);
AuthWeChatOpenRequest request = new AuthWeChatOpenRequest(config);
String authorize = request.authorize("state");
System.out.println(authorize);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册