Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions CHANGELOGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
### 2024/12/14

- 新增
- 添加`微信小程序`登录能力。
- 添加`支付宝证书模式`登录能力(原支持的公钥登录模式依然可用)。
- 添加`appleid`社交登录能力。 [Github#192](https://github.com/justauth/JustAuth/pull/192)
- 添加`微信小程序`登录能力,对接文档:[点击查看](https://justauth.cn/guide/oauth/wechat_mini_program/)
- 添加`支付宝证书模式`登录能力(原支持的公钥登录模式依然可用),对接文档:[点击查看](https://justauth.cn/guide/oauth/alipay_cert)
- 添加`appleid`社交登录能力,对接文档:[点击查看](https://justauth.cn/guide/oauth/appleid/)。 [Github#192](https://github.com/justauth/JustAuth/pull/192)
- 添加`QQ小程序`社交登录能力。 [Github#223](https://github.com/justauth/JustAuth/pull/223)
- 添加`figma`社交登录能力。 [Gitee#41](https://gitee.com/yadong.zhang/JustAuth/pulls/41)
- 添加新版`企业微信扫码`登录能力。 [Github Issue#165](https://github.com/justauth/JustAuth/issues/165)
- 添加新版`钉钉扫码`登录能力。 [Gitee Issue#I73FZL](https://gitee.com/yadong.zhang/JustAuth/issues/I73FZL)
- 添加新版`华为`登录能力,原`AuthHuaweiRequest`会在后面版本被弃用,如有使用,请切换到`AuthHuaweiV3Request`
- 添加新版`企业微信扫码`登录能力,对接文档:[点击查看](https://justauth.cn/guide/oauth/wechat_enterprise_qrcode_v2/)。 [Github Issue#165](https://github.com/justauth/JustAuth/issues/165)
- 添加新版`钉钉扫码`登录能力,对接文档:[点击查看](https://justauth.cn/guide/oauth/dingtalk_v2/)。 [Gitee Issue#I73FZL](https://gitee.com/yadong.zhang/JustAuth/issues/I73FZL)
- 添加新版`华为`登录能力,对接文档:[点击查看](https://justauth.cn/guide/oauth/huawei_v3/),原`AuthHuaweiRequest`会在后面版本被弃用,如有使用,请切换到`AuthHuaweiV3Request`
- 优化
- 修复文档错误。[Github #222](https://github.com/justauth/JustAuth/pull/222)
- 更新 Google 端点地址。[Github #198](https://github.com/justauth/JustAuth/pull/198)
Expand Down
112 changes: 107 additions & 5 deletions src/main/java/me/zhyd/oauth/config/AuthDefaultSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,58 @@

import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.request.*;
import me.zhyd.oauth.request.AuthAlipayRequest;
import me.zhyd.oauth.request.AuthAliyunRequest;
import me.zhyd.oauth.request.AuthAmazonRequest;
import me.zhyd.oauth.request.AuthAppleRequest;
import me.zhyd.oauth.request.AuthBaiduRequest;
import me.zhyd.oauth.request.AuthCodingRequest;
import me.zhyd.oauth.request.AuthCsdnRequest;
import me.zhyd.oauth.request.AuthDefaultRequest;
import me.zhyd.oauth.request.AuthDingTalkAccountRequest;
import me.zhyd.oauth.request.AuthDingTalkRequest;
import me.zhyd.oauth.request.AuthDingTalkV2Request;
import me.zhyd.oauth.request.AuthDouyinMiniProgramRequest;
import me.zhyd.oauth.request.AuthDouyinRequest;
import me.zhyd.oauth.request.AuthElemeRequest;
import me.zhyd.oauth.request.AuthFacebookRequest;
import me.zhyd.oauth.request.AuthFeishuRequest;
import me.zhyd.oauth.request.AuthFigmaRequest;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.request.AuthGithubRequest;
import me.zhyd.oauth.request.AuthGitlabRequest;
import me.zhyd.oauth.request.AuthGoogleRequest;
import me.zhyd.oauth.request.AuthHuaweiRequest;
import me.zhyd.oauth.request.AuthHuaweiV3Request;
import me.zhyd.oauth.request.AuthJdRequest;
import me.zhyd.oauth.request.AuthKujialeRequest;
import me.zhyd.oauth.request.AuthLineRequest;
import me.zhyd.oauth.request.AuthLinkedinRequest;
import me.zhyd.oauth.request.AuthMeituanRequest;
import me.zhyd.oauth.request.AuthMiRequest;
import me.zhyd.oauth.request.AuthMicrosoftCnRequest;
import me.zhyd.oauth.request.AuthMicrosoftRequest;
import me.zhyd.oauth.request.AuthOktaRequest;
import me.zhyd.oauth.request.AuthOschinaRequest;
import me.zhyd.oauth.request.AuthPinterestRequest;
import me.zhyd.oauth.request.AuthProginnRequest;
import me.zhyd.oauth.request.AuthQqRequest;
import me.zhyd.oauth.request.AuthRenrenRequest;
import me.zhyd.oauth.request.AuthSlackRequest;
import me.zhyd.oauth.request.AuthStackOverflowRequest;
import me.zhyd.oauth.request.AuthTaobaoRequest;
import me.zhyd.oauth.request.AuthTeambitionRequest;
import me.zhyd.oauth.request.AuthToutiaoRequest;
import me.zhyd.oauth.request.AuthTwitterRequest;
import me.zhyd.oauth.request.AuthWeChatEnterpriseQrcodeRequest;
import me.zhyd.oauth.request.AuthWeChatEnterpriseQrcodeV2Request;
import me.zhyd.oauth.request.AuthWeChatEnterpriseThirdQrcodeRequest;
import me.zhyd.oauth.request.AuthWeChatEnterpriseWebRequest;
import me.zhyd.oauth.request.AuthWeChatMpRequest;
import me.zhyd.oauth.request.AuthWeChatOpenRequest;
import me.zhyd.oauth.request.AuthWechatMiniProgramRequest;
import me.zhyd.oauth.request.AuthWeiboRequest;
import me.zhyd.oauth.request.AuthXmlyRequest;

/**
* JustAuth内置的各api需要的url, 用枚举类分平台类型管理
Expand Down Expand Up @@ -565,7 +616,9 @@ public String refresh() {
}

@Override
public Class<? extends AuthDefaultRequest> getTargetClass() { return AuthMicrosoftCnRequest.class; }
public Class<? extends AuthDefaultRequest> getTargetClass() {
return AuthMicrosoftCnRequest.class;
}
},
/**
* 小米
Expand Down Expand Up @@ -732,7 +785,7 @@ public Class<? extends AuthDefaultRequest> getTargetClass() {

/**
* 华为
*
* <p>
* 当前方式未来可能被废弃,建议使用 {@link this#HUAWEI_V3}
*
* @since 1.10.0
Expand Down Expand Up @@ -1409,7 +1462,7 @@ public Class<? extends AuthDefaultRequest> getTargetClass() {
}
},

FIGMA{
FIGMA {
@Override
public String authorize() {
return "https://www.figma.com/oauth";
Expand Down Expand Up @@ -1437,10 +1490,10 @@ public Class<? extends AuthDefaultRequest> getTargetClass() {
},
/**
* 微信小程序授权登录
*
* @since yudaocode
*/
WECHAT_MINI_PROGRAM {

@Override
public String authorize() {
// 参见 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 文档
Expand Down Expand Up @@ -1493,6 +1546,55 @@ public String userInfo() {
public Class<? extends AuthDefaultRequest> getTargetClass() {
return null;
}
},

/**
* 抖音小程序授权
*/
DOUYIN_MINI_PROGRAM {
/**
* 授权的api
*
* @return url
*/
@Override
public String authorize() {
// 参见 https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/open-capacity/log-in/tt-login 文档
throw new UnsupportedOperationException("不支持获取授权 url,请使用小程序内置函数 tt.login() 登录获取 code");
}

/**
* 获取accessToken的api
*
* @return url
*/
@Override
public String accessToken() {
// 参见 https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/server/log-in/code-2-session 文档
// 获取 openid, unionId , session_key 等字段
return "https://minigame.zijieapi.com/mgplatform/api/apps/jscode2session";
}

/**
* 获取用户信息的api
*
* @return url
*/
@Override
public String userInfo() {
// 参见 https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/guide/open-api/info/tt-get-user-info 文档
throw new UnsupportedOperationException("不支持获取用户信息 url,请使用小程序内置函数 tt.getUserInfo() 获取用户信息");
}

/**
* 平台对应的 AuthRequest 实现类,必须继承自 {@link AuthDefaultRequest}
*
* @return class
*/
@Override
public Class<? extends AuthDefaultRequest> getTargetClass() {
return AuthDouyinMiniProgramRequest.class;
}
}

}
7 changes: 7 additions & 0 deletions src/main/java/me/zhyd/oauth/model/AuthCallback.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public class AuthCallback implements Serializable {
*/
private String code;

/**
* 该参数目前只使用于抖音小程序匿名登录
*/
private String anonymous_code;

/**
* 访问AuthorizeUrl后回调时带的参数auth_code,该参数目前只使用于支付宝登录
*/
Expand Down Expand Up @@ -60,12 +65,14 @@ public class AuthCallback implements Serializable {

/**
* 苹果仅在用户首次授权应用程序时返回此值。如果您的应用程序已经获得了用户的授权,那么苹果将不会再次返回此值
*
* @see <a href="https://developer.apple.com/documentation/sign_in_with_apple/useri">user info</a>
*/
private String user;

/**
* 苹果错误信息,仅在用户取消授权时返回此值
*
* @see <a href="https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms">error response</a>
*/
private String error;
Expand Down
13 changes: 11 additions & 2 deletions src/main/java/me/zhyd/oauth/model/AuthToken.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package me.zhyd.oauth.model;

import lombok.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.Serializable;

Expand Down Expand Up @@ -46,7 +50,7 @@ public class AuthToken implements Serializable {
private String code;
/**
* 微信公众号 - 网页授权的登录时可用
*
* <p>
* 微信针对网页授权登录,增加了一个快照页的逻辑,快照页获取到的微信用户的 uid oid 和头像昵称都是虚拟的信息
*/
private boolean snapshotUser;
Expand All @@ -73,4 +77,9 @@ public class AuthToken implements Serializable {
* @since 1.16.7
*/
private String corpId;

/**
* 抖音小程序附带属性
*/
private String anonymousOpenid;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package me.zhyd.oauth.request;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.HttpUtils;
import me.zhyd.oauth.utils.UrlBuilder;

/**
* @author JackyTang (jackytang01(a)gmail.com)
* @version 1.0
* @website
* @date 2024/04/22 00:06
* @since 17
*/
public class AuthDouyinMiniProgramRequest extends AuthDefaultRequest {
public AuthDouyinMiniProgramRequest(AuthConfig config) {
super(config, AuthDefaultSource.DOUYIN_MINI_PROGRAM);
}

public AuthDouyinMiniProgramRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthDefaultSource.DOUYIN_MINI_PROGRAM, authStateCache);
}

@Override
public AuthToken getAccessToken(AuthCallback authCallback) {
// 参见 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html 文档
// 使用 code 获取对应的 openId、unionId 等字段
String response = new HttpUtils(config.getHttpConfig()).get(accessTokenUrl(authCallback.getCode(), authCallback.getAnonymous_code())).getBody();
JSCode2SessionResponse accessTokenObject = JSONObject.parseObject(response, JSCode2SessionResponse.class);
assert accessTokenObject != null;
checkResponse(accessTokenObject);
// 拼装结果
return AuthToken.builder()
.openId(accessTokenObject.getOpenid())
.unionId(accessTokenObject.getUnionId())
.accessToken(accessTokenObject.getSessionKey())
.anonymousOpenid(accessTokenObject.anonymousOpenid)
.build();
}

@Override
public AuthUser getUserInfo(AuthToken authToken) {
// 参见 https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/guide/open-api/info/tt-get-user-info 文档
// 如果需要用户信息,需要在小程序调用函数后传给后端
return AuthUser.builder()
.username("")
.nickname("")
.avatar("")
.uuid(authToken.getOpenId())
.token(authToken)
.source(source.toString())
.build();
}

private void checkResponse(JSCode2SessionResponse response) {
if (response.getError() != 0) {
throw new AuthException(response.getErrorCode(), response.getErrorMsg());
}
}

private String accessTokenUrl(String code, String anonymousCode) {
return UrlBuilder.fromBaseUrl(source.accessToken())
.queryParam("appid", config.getClientId())
.queryParam("secret", config.getClientSecret())
.queryParam("code", code)
.queryParam("anonymous_code", anonymousCode)
.build();
}

@Data
@SuppressWarnings("SpellCheckingInspection")
private static class JSCode2SessionResponse {

@JSONField(name = "error")
private int error;
@JSONField(name = "errcode")
private int errorCode;
@JSONField(name = "errmsg")
private String errorMsg;
@JSONField(name = "session_key")
private String sessionKey;
@JSONField(name = "openid")
private String openid;
@JSONField(name = "anonymous_openid")
private String anonymousOpenid;
@JSONField(name = "unionid")
private String unionId;

}

}