mirror of
https://gitee.com/yadong.zhang/JustAuth.git
synced 2025-12-06 16:58:24 +08:00
🥚 正式启用飞书登录
This commit is contained in:
parent
2ff5570399
commit
9fd2b9b919
@ -3,6 +3,9 @@
|
||||
### 2021/1/1
|
||||
|
||||
- 发布 v1.15.9
|
||||
- 新增
|
||||
- 修复并正式启用 飞书 平台的第三方登录
|
||||
- AuthToken 类中新增 `refreshTokenExpireIn` 记录 refresh token 的有效期
|
||||
- PR
|
||||
- 合并 [Github #101](https://gitee.com/yadong.zhang/JustAuth/pulls/101):支持喜马拉雅登录
|
||||
- 合并 [Github #105](https://gitee.com/yadong.zhang/JustAuth/pulls/105):支持企业微信网页授权登录
|
||||
|
||||
@ -141,7 +141,7 @@ public enum AuthDefaultSource implements AuthSource {
|
||||
},
|
||||
/**
|
||||
* Coding,
|
||||
*
|
||||
* <p>
|
||||
* 参考 https://help.coding.net/docs/project/open/oauth.html#%E7%94%A8%E6%88%B7%E6%8E%88%E6%9D%83 中的说明,
|
||||
* 新版的 coding API 地址需要传入用户团队名,这儿使用动态参数,方便在 request 中使用
|
||||
*/
|
||||
@ -730,30 +730,31 @@ public enum AuthDefaultSource implements AuthSource {
|
||||
},
|
||||
|
||||
/**
|
||||
* 飞书
|
||||
* 注意:该平台暂时存在问题,请不要使用。待修复完成后会重新发版
|
||||
* 飞书平台,企业自建应用授权登录,原逻辑由 beacon 集成于 1.14.0 版,但最新的飞书 api 已修改,并且飞书平台一直为 {@code Deprecated} 状态
|
||||
* <p>
|
||||
* 所以,最终修改该平台的实际发布版本为 1.15.9
|
||||
*
|
||||
* @since 1.14.0
|
||||
* @since 1.15.9
|
||||
*/
|
||||
FEISHU {
|
||||
@Override
|
||||
public String authorize() {
|
||||
return "https://open.feishu.cn/connect/qrconnect/page/sso/";
|
||||
return "https://open.feishu.cn/open-apis/authen/v1/index";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String accessToken() {
|
||||
return "https://open.feishu.cn/connect/qrconnect/oauth2/access_token/";
|
||||
return "https://open.feishu.cn/open-apis/authen/v1/access_token";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String userInfo() {
|
||||
return "https://open.feishu.cn/connect/qrconnect/oauth2/user_info/";
|
||||
return "https://open.feishu.cn/open-apis/authen/v1/user_info";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String refresh() {
|
||||
return "https://open.feishu.cn/connect/qrconnect/oauth2/access_token/";
|
||||
return "https://open.feishu.cn/open-apis/authen/v1/refresh_access_token";
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
||||
@ -19,6 +19,7 @@ public class AuthToken implements Serializable {
|
||||
private String accessToken;
|
||||
private int expireIn;
|
||||
private String refreshToken;
|
||||
private int refreshTokenExpireIn;
|
||||
private String uid;
|
||||
private String openId;
|
||||
private String accessCode;
|
||||
|
||||
@ -3,9 +3,11 @@ package me.zhyd.oauth.request;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.xkcoding.http.support.HttpHeader;
|
||||
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;
|
||||
@ -13,40 +15,63 @@ import me.zhyd.oauth.model.AuthToken;
|
||||
import me.zhyd.oauth.model.AuthUser;
|
||||
import me.zhyd.oauth.utils.GlobalAuthUtils;
|
||||
import me.zhyd.oauth.utils.HttpUtils;
|
||||
import me.zhyd.oauth.utils.StringUtils;
|
||||
import me.zhyd.oauth.utils.UrlBuilder;
|
||||
|
||||
/**
|
||||
* 注意:该平台暂时存在问题,请不要使用。待修复完成后会重新发版by yadong.zhang
|
||||
* 飞书平台,企业自建应用授权登录,原逻辑由 beacon 集成于 1.14.0 版,但最新的飞书 api 已修改,并且飞书平台一直为 {@code Deprecated} 状态
|
||||
* <p>
|
||||
* 所以,最终修改该平台的实际发布版本为 1.15.9
|
||||
*
|
||||
* @author beacon
|
||||
* @since 1.14.0
|
||||
* @author yadong.zhang (yadong.zhang0415(a)gmail.com) 重构业务逻辑 20210101
|
||||
* @since 1.15.9
|
||||
*/
|
||||
@Deprecated
|
||||
public class AuthFeishuRequest extends AuthDefaultRequest {
|
||||
|
||||
public AuthFeishuRequest(AuthConfig config) {
|
||||
super(config, AuthDefaultSource.FEISHU);
|
||||
throw new AuthException(AuthResponseStatus.FAILURE);
|
||||
}
|
||||
|
||||
public AuthFeishuRequest(AuthConfig config, AuthStateCache authStateCache) {
|
||||
super(config, AuthDefaultSource.FEISHU, authStateCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 app_access_token(企业自建应用)
|
||||
* <p>
|
||||
* Token 有效期为 2 小时,在此期间调用该接口 token 不会改变。当 token 有效期小于 30 分的时候,再次请求获取 token 的时候,
|
||||
* 会生成一个新的 token,与此同时老的 token 依然有效。
|
||||
*
|
||||
* @return appAccessToken
|
||||
*/
|
||||
private String getAppAccessToken() {
|
||||
String cacheKey = this.source.getName().concat(":app_access_token:").concat(config.getClientId());
|
||||
String cacheAppAccessToken = this.authStateCache.get(cacheKey);
|
||||
if (StringUtils.isNotEmpty(cacheAppAccessToken)) {
|
||||
return cacheAppAccessToken;
|
||||
}
|
||||
String url = "https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal/";
|
||||
JSONObject requestObject = new JSONObject();
|
||||
requestObject.put("app_id", config.getClientId());
|
||||
requestObject.put("app_secret", config.getClientSecret());
|
||||
String response = new HttpUtils(config.getHttpConfig()).post(url, requestObject.toJSONString(), new HttpHeader()
|
||||
.add("Content-Type", "application/json"));
|
||||
JSONObject jsonObject = JSON.parseObject(response);
|
||||
this.checkResponse(jsonObject);
|
||||
String appAccessToken = jsonObject.getString("app_access_token");
|
||||
// 缓存 app access token
|
||||
this.authStateCache.cache(cacheKey, appAccessToken, jsonObject.getLongValue("expire") * 1000);
|
||||
return appAccessToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
||||
JSONObject requestObject = new JSONObject();
|
||||
requestObject.put("app_id", config.getClientId());
|
||||
requestObject.put("app_secret", config.getClientSecret());
|
||||
requestObject.put("app_access_token", this.getAppAccessToken());
|
||||
requestObject.put("grant_type", "authorization_code");
|
||||
requestObject.put("code", authCallback.getCode());
|
||||
String response = new HttpUtils(config.getHttpConfig()).post(source.accessToken(), requestObject.toJSONString(), new HttpHeader()
|
||||
.add("Content-Type", "application/json"));
|
||||
JSONObject jsonObject = JSON.parseObject(response);
|
||||
this.checkResponse(jsonObject);
|
||||
return AuthToken.builder()
|
||||
.accessToken(jsonObject.getString("access_token"))
|
||||
.refreshToken(jsonObject.getString("refresh_token"))
|
||||
.expireIn(jsonObject.getIntValue("expires_in"))
|
||||
.tokenType(jsonObject.getString("token_type"))
|
||||
.openId(jsonObject.getString("open_id"))
|
||||
.build();
|
||||
return getToken(requestObject, this.source.accessToken());
|
||||
|
||||
}
|
||||
|
||||
@ -57,37 +82,47 @@ public class AuthFeishuRequest extends AuthDefaultRequest {
|
||||
.add("Content-Type", "application/json")
|
||||
.add("Authorization", "Bearer " + accessToken), false);
|
||||
JSONObject object = JSON.parseObject(response);
|
||||
this.checkResponse(object);
|
||||
JSONObject data = object.getJSONObject("data");
|
||||
return AuthUser.builder()
|
||||
.rawUserInfo(object)
|
||||
.avatar(object.getString("AvatarUrl"))
|
||||
.username(object.getString("Mobile"))
|
||||
.email(object.getString("Email"))
|
||||
.nickname("Name")
|
||||
.uuid(data.getString("union_id"))
|
||||
.username(data.getString("name"))
|
||||
.nickname(data.getString("name"))
|
||||
.avatar(data.getString("avatar_url"))
|
||||
.email(data.getString("email"))
|
||||
.gender(AuthUserGender.UNKNOWN)
|
||||
.token(authToken)
|
||||
.source(source.toString())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthResponse refresh(AuthToken authToken) {
|
||||
JSONObject requestObject = new JSONObject();
|
||||
requestObject.put("app_id", config.getClientId());
|
||||
requestObject.put("app_secret", config.getClientSecret());
|
||||
requestObject.put("app_access_token", this.getAppAccessToken());
|
||||
requestObject.put("grant_type", "refresh_token");
|
||||
requestObject.put("refresh_token", authToken.getRefreshToken());
|
||||
String response = new HttpUtils(config.getHttpConfig()).post(source.refresh(), requestObject.toJSONString(), new HttpHeader()
|
||||
return AuthResponse.builder()
|
||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||
.data(getToken(requestObject, this.source.refresh()))
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
private AuthToken getToken(JSONObject param, String url) {
|
||||
String response = new HttpUtils(config.getHttpConfig()).post(url, param.toJSONString(), new HttpHeader()
|
||||
.add("Content-Type", "application/json"));
|
||||
JSONObject jsonObject = JSON.parseObject(response);
|
||||
this.checkResponse(jsonObject);
|
||||
return AuthResponse.builder()
|
||||
.code(AuthResponseStatus.SUCCESS.getCode())
|
||||
.data(AuthToken.builder()
|
||||
.accessToken(jsonObject.getString("access_token"))
|
||||
.refreshToken(jsonObject.getString("refresh_token"))
|
||||
.expireIn(jsonObject.getIntValue("expires_in"))
|
||||
.tokenType(jsonObject.getString("token_type"))
|
||||
.openId(jsonObject.getString("open_id"))
|
||||
.build())
|
||||
JSONObject data = jsonObject.getJSONObject("data");
|
||||
return AuthToken.builder()
|
||||
.accessToken(data.getString("access_token"))
|
||||
.refreshToken(data.getString("refresh_token"))
|
||||
.expireIn(data.getIntValue("expires_in"))
|
||||
.tokenType(data.getString("token_type"))
|
||||
.openId(data.getString("open_id"))
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user