mirror of
https://gitee.com/yadong.zhang/JustAuth.git
synced 2025-12-07 01:08:24 +08:00
commit
e04d2abe3a
6
pom.xml
6
pom.xml
@ -31,6 +31,11 @@
|
|||||||
<email>yadong.zhang0415@gmail.com</email>
|
<email>yadong.zhang0415@gmail.com</email>
|
||||||
<url>https://www.zhyd.me</url>
|
<url>https://www.zhyd.me</url>
|
||||||
</developer>
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<name>Yangkai.Shen</name>
|
||||||
|
<email>shenyangkai1994@gmail.com</email>
|
||||||
|
<url>https://xkcoding.com</url>
|
||||||
|
</developer>
|
||||||
</developers>
|
</developers>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@ -46,6 +51,7 @@
|
|||||||
<junit-version>4.11</junit-version>
|
<junit-version>4.11</junit-version>
|
||||||
<fastjson-version>1.2.44</fastjson-version>
|
<fastjson-version>1.2.44</fastjson-version>
|
||||||
<google-api-version>1.28.0</google-api-version>
|
<google-api-version>1.28.0</google-api-version>
|
||||||
|
<guava-version>27.1-jre</guava-version>
|
||||||
<alipay-sdk-version>3.7.4.ALL</alipay-sdk-version>
|
<alipay-sdk-version>3.7.4.ALL</alipay-sdk-version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|||||||
@ -329,6 +329,35 @@ public enum ApiUrl {
|
|||||||
public String refresh() {
|
public String refresh() {
|
||||||
throw new AuthException(ResponseStatus.UNSUPPORTED);
|
throw new AuthException(ResponseStatus.UNSUPPORTED);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 微信
|
||||||
|
*/
|
||||||
|
WECHAT {
|
||||||
|
@Override
|
||||||
|
public String authorize() {
|
||||||
|
return "https://open.weixin.qq.com/connect/qrconnect";
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 revoke() {
|
||||||
|
throw new AuthException(ResponseStatus.UNSUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String refresh() {
|
||||||
|
return "https://api.weixin.qq.com/sns/oauth2/refresh_token";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public abstract String authorize();
|
public abstract String authorize();
|
||||||
|
|||||||
106
src/main/java/me/zhyd/oauth/request/AuthWeChatRequest.java
Normal file
106
src/main/java/me/zhyd/oauth/request/AuthWeChatRequest.java
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package me.zhyd.oauth.request;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpResponse;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import me.zhyd.oauth.config.AuthConfig;
|
||||||
|
import me.zhyd.oauth.exception.AuthException;
|
||||||
|
import me.zhyd.oauth.model.AuthResponse;
|
||||||
|
import me.zhyd.oauth.model.AuthSource;
|
||||||
|
import me.zhyd.oauth.model.AuthUser;
|
||||||
|
import me.zhyd.oauth.model.AuthUserGender;
|
||||||
|
import me.zhyd.oauth.utils.UrlBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 微信登录
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @package: me.zhyd.oauth.request
|
||||||
|
* @description: 微信登录
|
||||||
|
* @author: yangkai.shen
|
||||||
|
* @date: Created in 2019-05-17 11:11
|
||||||
|
* @copyright: Copyright (c) 2019
|
||||||
|
* @version: V1.0
|
||||||
|
* @modified: yangkai.shen
|
||||||
|
*/
|
||||||
|
public class AuthWeChatRequest extends BaseAuthRequest {
|
||||||
|
public AuthWeChatRequest(AuthConfig config) {
|
||||||
|
super(config, AuthSource.WECHAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信的特殊性,此时返回的信息同时包含 openid 和 access_token
|
||||||
|
*
|
||||||
|
* @param code 授权码
|
||||||
|
* @return 所有信息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAccessToken(String code) {
|
||||||
|
String accessTokenUrl = UrlBuilder.getWeChatAccessTokenUrl(config.getClientId(), config.getClientSecret(), code);
|
||||||
|
HttpResponse response = HttpRequest.get(accessTokenUrl).execute();
|
||||||
|
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
|
||||||
|
if (!accessTokenObject.containsKey("access_token") || !accessTokenObject.containsKey("openid") || !accessTokenObject
|
||||||
|
.containsKey("refresh_token")) {
|
||||||
|
throw new AuthException("Unable to get access_token or openid or refresh_token from wechat using code [" + code + "]");
|
||||||
|
}
|
||||||
|
return response.body();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AuthUser getUserInfo(String accessToken) {
|
||||||
|
String token = this.getToken(accessToken);
|
||||||
|
String openId = this.getOpenId(accessToken);
|
||||||
|
|
||||||
|
HttpResponse response = HttpRequest.get(UrlBuilder.getWeChatUserInfoUrl(token, openId)).execute();
|
||||||
|
JSONObject object = JSONObject.parseObject(response.body());
|
||||||
|
if (object.containsKey("errcode")) {
|
||||||
|
throw new AuthException(object.getString("errmsg"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return AuthUser.builder()
|
||||||
|
.username(object.getString("nickname"))
|
||||||
|
.nickname(object.getString("nickname"))
|
||||||
|
.avatar(object.getString("headimgurl"))
|
||||||
|
.location(object.getString("country") + "-" + object.getString("province") + "-" + object.getString("city"))
|
||||||
|
.gender(AuthUserGender.getRealGender(object.getString("sex")))
|
||||||
|
.accessToken(accessToken)
|
||||||
|
.source(AuthSource.WECHAT)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新access token (续期)
|
||||||
|
*
|
||||||
|
* @param accessToken 登录成功后返回的accessToken
|
||||||
|
* @return AuthResponse
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AuthResponse refresh(String accessToken) {
|
||||||
|
String refreshToken = getRefreshToken(accessToken);
|
||||||
|
HttpResponse response = HttpRequest.get(UrlBuilder.getWeChatRefreshUrl(config.getClientId(), refreshToken))
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
JSONObject object = JSONObject.parseObject(response.body());
|
||||||
|
if (object.containsKey("errcode")) {
|
||||||
|
throw new AuthException(object.getString("errmsg"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return AuthResponse.builder().data(object).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRefreshToken(String accessToken) {
|
||||||
|
JSONObject accessTokenObject = JSONObject.parseObject(accessToken);
|
||||||
|
return accessTokenObject.getString("refresh_token");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getOpenId(String accessToken) {
|
||||||
|
JSONObject accessTokenObject = JSONObject.parseObject(accessToken);
|
||||||
|
return accessTokenObject.getString("openid");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getToken(String accessToken) {
|
||||||
|
JSONObject accessTokenObject = JSONObject.parseObject(accessToken);
|
||||||
|
return accessTokenObject.getString("access_token");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -79,6 +79,7 @@ public abstract class BaseAuthRequest implements AuthRequest {
|
|||||||
authorizeUrl = UrlBuilder.getQqAuthorizeUrl(config.getClientId(), config.getRedirectUri());
|
authorizeUrl = UrlBuilder.getQqAuthorizeUrl(config.getClientId(), config.getRedirectUri());
|
||||||
break;
|
break;
|
||||||
case WECHAT:
|
case WECHAT:
|
||||||
|
authorizeUrl = UrlBuilder.getWeChatAuthorizeUrl(config.getClientId(), config.getRedirectUri());
|
||||||
break;
|
break;
|
||||||
case GOOGLE:
|
case GOOGLE:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -56,6 +56,11 @@ public class UrlBuilder {
|
|||||||
private static final String QQ_AUTHORIZE_PATTERN = "{0}?client_id={1}&response_type=code&redirect_uri={2}&state={3}";
|
private static final String QQ_AUTHORIZE_PATTERN = "{0}?client_id={1}&response_type=code&redirect_uri={2}&state={3}";
|
||||||
private static final String QQ_OPENID_PATTERN = "{0}?access_token={1}";
|
private static final String QQ_OPENID_PATTERN = "{0}?access_token={1}";
|
||||||
|
|
||||||
|
private static final String WECHAT_AUTHORIZE_PATTERN = "{0}?appid={1}&redirect_uri={2}&response_type=code&scope=snsapi_login&state={3}#wechat_redirect";
|
||||||
|
private static final String WECHAT_ACCESS_TOKEN_PATTERN = "{0}?appid={1}&secret={2}&code={3}&grant_type=authorization_code";
|
||||||
|
private static final String WECHAT_REFRESH_TOKEN_PATTERN = "{0}?appid={1}&grant_type=refresh_token&refresh_token={2}";
|
||||||
|
private static final String WECHAT_USER_INFO_PATTERN = "{0}?access_token={1}&openid={2}&lang=zh_CN";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取githubtoken的接口地址
|
* 获取githubtoken的接口地址
|
||||||
*
|
*
|
||||||
@ -415,4 +420,49 @@ public class UrlBuilder {
|
|||||||
public static String getAlipayAuthorizeUrl(String clientId, String redirectUrl) {
|
public static String getAlipayAuthorizeUrl(String clientId, String redirectUrl) {
|
||||||
return MessageFormat.format(ALIPAY_AUTHORIZE_PATTERN, ApiUrl.ALIPAY.authorize(), clientId, redirectUrl);
|
return MessageFormat.format(ALIPAY_AUTHORIZE_PATTERN, ApiUrl.ALIPAY.authorize(), clientId, redirectUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取微信 授权地址
|
||||||
|
*
|
||||||
|
* @param clientId 微信应用的appid
|
||||||
|
* @param redirectUrl 微信应用授权成功后的回调地址
|
||||||
|
* @return full url
|
||||||
|
*/
|
||||||
|
public static String getWeChatAuthorizeUrl(String clientId, String redirectUrl) {
|
||||||
|
return MessageFormat.format(WECHAT_AUTHORIZE_PATTERN, ApiUrl.WECHAT.authorize(), clientId, redirectUrl, System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取微信 token的接口地址
|
||||||
|
*
|
||||||
|
* @param clientId 微信应用的appid
|
||||||
|
* @param clientSecret 微信应用的secret
|
||||||
|
* @param code 微信授权前的code,用来换token
|
||||||
|
* @return full url
|
||||||
|
*/
|
||||||
|
public static String getWeChatAccessTokenUrl(String clientId, String clientSecret, String code) {
|
||||||
|
return MessageFormat.format(WECHAT_ACCESS_TOKEN_PATTERN, ApiUrl.WECHAT.accessToken(), clientId, clientSecret, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取微信 用户详情的接口地址
|
||||||
|
*
|
||||||
|
* @param token 微信应用返回的 access token
|
||||||
|
* @param openId 微信应用返回的openId
|
||||||
|
* @return full url
|
||||||
|
*/
|
||||||
|
public static String getWeChatUserInfoUrl(String token, String openId) {
|
||||||
|
return MessageFormat.format(WECHAT_USER_INFO_PATTERN, ApiUrl.WECHAT.userInfo(), token, openId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取微信 刷新令牌 地址
|
||||||
|
*
|
||||||
|
* @param clientId 微信应用的appid
|
||||||
|
* @param refreshToken 微信应用返回的刷新token
|
||||||
|
* @return full url
|
||||||
|
*/
|
||||||
|
public static String getWeChatRefreshUrl(String clientId, String refreshToken) {
|
||||||
|
return MessageFormat.format(WECHAT_REFRESH_TOKEN_PATTERN, ApiUrl.WECHAT.refresh(), clientId, refreshToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package me.zhyd.oauth;
|
package me.zhyd.oauth;
|
||||||
|
|
||||||
import me.zhyd.oauth.config.AuthConfig;
|
import me.zhyd.oauth.config.AuthConfig;
|
||||||
|
import me.zhyd.oauth.model.AuthResponse;
|
||||||
import me.zhyd.oauth.request.*;
|
import me.zhyd.oauth.request.*;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -114,4 +115,17 @@ public class AuthRequestTest {
|
|||||||
// 授权登录后会返回一个code,用这个code进行登录
|
// 授权登录后会返回一个code,用这个code进行登录
|
||||||
authRequest.login("code");
|
authRequest.login("code");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void wechatTest() {
|
||||||
|
AuthRequest authRequest = new AuthWeChatRequest(AuthConfig.builder()
|
||||||
|
.clientId("clientId")
|
||||||
|
.clientSecret("clientSecret")
|
||||||
|
.redirectUri("redirectUri")
|
||||||
|
.build());
|
||||||
|
// 返回授权页面,可自行调整
|
||||||
|
String url = authRequest.authorize();
|
||||||
|
// 授权登录后会返回一个code,用这个code进行登录
|
||||||
|
AuthResponse login = authRequest.login("code");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user