Skip to content

Commit 56bfe28

Browse files
authored
Merge pull request #223 from hurentian/dev
feat: 支持QQ小程序
2 parents 89d107f + 4b07aec commit 56bfe28

File tree

3 files changed

+135
-0
lines changed

3 files changed

+135
-0
lines changed

src/main/java/me/zhyd/oauth/config/AuthDefaultSource.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,6 +1464,35 @@ public String userInfo() {
14641464
public Class<? extends AuthDefaultRequest> getTargetClass() {
14651465
return AuthWechatMiniProgramRequest.class;
14661466
}
1467+
},
1468+
1469+
/**
1470+
* QQ小程序授权登录
1471+
*/
1472+
QQ_MINI_PROGRAM {
1473+
@Override
1474+
public String authorize() {
1475+
// 参见 https://q.qq.com/wiki/develop/miniprogram/frame/open_ability/open_userinfo.html 文档
1476+
throw new UnsupportedOperationException("不支持获取授权 url,请使用小程序内置函数 qq.login() 登录获取 code");
1477+
}
1478+
1479+
@Override
1480+
public String accessToken() {
1481+
// 参见 https://q.qq.com/wiki/develop/miniprogram/server/open_port/port_login.html 文档
1482+
// 获取 openid, unionId , session_key 等字段
1483+
return "https://api.q.qq.com/sns/jscode2session";
1484+
}
1485+
1486+
@Override
1487+
public String userInfo() {
1488+
// 参见 https://q.qq.com/wiki/develop/miniprogram/API/open_port/port_userinfo.html 文档
1489+
throw new UnsupportedOperationException("不支持获取用户信息 url,请使用小程序内置函数 qq.getUserInfo() 获取用户信息");
1490+
}
1491+
1492+
@Override
1493+
public Class<? extends AuthDefaultRequest> getTargetClass() {
1494+
return null;
1495+
}
14671496
}
14681497

14691498
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package me.zhyd.oauth.request;
2+
3+
import com.alibaba.fastjson.JSONObject;
4+
import com.alibaba.fastjson.annotation.JSONField;
5+
import lombok.Data;
6+
import me.zhyd.oauth.cache.AuthStateCache;
7+
import me.zhyd.oauth.config.AuthConfig;
8+
import me.zhyd.oauth.config.AuthDefaultSource;
9+
import me.zhyd.oauth.exception.AuthException;
10+
import me.zhyd.oauth.model.AuthCallback;
11+
import me.zhyd.oauth.model.AuthToken;
12+
import me.zhyd.oauth.model.AuthUser;
13+
import me.zhyd.oauth.utils.HttpUtils;
14+
import me.zhyd.oauth.utils.UrlBuilder;
15+
16+
/**
17+
* QQ小程序登陆 Request 请求
18+
* <p>
19+
* 参照微信小程序实现
20+
*
21+
* @author hurentian
22+
* @since 2024-10-08
23+
*/
24+
public class AuthQQMiniProgramRequest extends AuthDefaultRequest {
25+
public AuthQQMiniProgramRequest(AuthConfig config) {
26+
super(config, AuthDefaultSource.QQ_MINI_PROGRAM);
27+
}
28+
29+
public AuthQQMiniProgramRequest(AuthConfig config, AuthStateCache authStateCache) {
30+
super(config, AuthDefaultSource.QQ_MINI_PROGRAM, authStateCache);
31+
}
32+
33+
@Override
34+
public AuthToken getAccessToken(AuthCallback authCallback) {
35+
// 参见 https://q.qq.com/wiki/develop/miniprogram/server/open_port/port_login.html#code2session 文档
36+
// 使用 code 获取对应的 openId、unionId 等字段
37+
String response = new HttpUtils(config.getHttpConfig()).get(accessTokenUrl(authCallback.getCode())).getBody();
38+
JSCode2SessionResponse accessTokenObject = JSONObject.parseObject(response, JSCode2SessionResponse.class);
39+
assert accessTokenObject != null;
40+
checkResponse(accessTokenObject);
41+
// 拼装结果
42+
return AuthToken.builder()
43+
.openId(accessTokenObject.getOpenid())
44+
.unionId(accessTokenObject.getUnionId())
45+
.accessToken(accessTokenObject.getSessionKey())
46+
.build();
47+
}
48+
49+
@Override
50+
public AuthUser getUserInfo(AuthToken authToken) {
51+
// 参见 https://q.qq.com/wiki/develop/game/API/open-port/user-info.html#qq-getuserinfo 文档
52+
// 如果需要用户信息,需要在小程序调用函数后传给后端
53+
return AuthUser.builder()
54+
.username("")
55+
.nickname("")
56+
.avatar("")
57+
.uuid(authToken.getOpenId())
58+
.token(authToken)
59+
.source(source.toString())
60+
.build();
61+
}
62+
63+
/**
64+
* 检查响应内容是否正确
65+
*
66+
* @param response 请求响应内容
67+
*/
68+
private void checkResponse(JSCode2SessionResponse response) {
69+
if (response.getErrorCode() != 0) {
70+
throw new AuthException(response.getErrorCode(), response.getErrorMsg());
71+
}
72+
}
73+
74+
@Override
75+
protected String accessTokenUrl(String code) {
76+
return UrlBuilder.fromBaseUrl(source.accessToken())
77+
.queryParam("appid", config.getClientId())
78+
.queryParam("secret", config.getClientSecret())
79+
.queryParam("js_code", code)
80+
.queryParam("grant_type", "authorization_code")
81+
.build();
82+
}
83+
84+
@Data
85+
@SuppressWarnings("SpellCheckingInspection")
86+
private static class JSCode2SessionResponse {
87+
88+
@JSONField(name = "errcode")
89+
private int errorCode;
90+
@JSONField(name = "errmsg")
91+
private String errorMsg;
92+
@JSONField(name = "session_key")
93+
private String sessionKey;
94+
private String openid;
95+
@JSONField(name = "unionid")
96+
private String unionId;
97+
98+
}
99+
100+
}

src/test/java/me/zhyd/oauth/AuthRequestBuilderTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ public void build4() {
107107
System.out.println(value.getTargetClass());
108108
continue;
109109
}
110+
case QQ_MINI_PROGRAM: {
111+
// 小程序不支持获取调用 authorize
112+
AuthRequest authRequest = new AuthQQMiniProgramRequest(config);
113+
System.out.println(value.getTargetClass());
114+
continue;
115+
}
110116
default:
111117
AuthRequest authRequest = AuthRequestBuilder.builder()
112118
.source(value.getName())

0 commit comments

Comments
 (0)