🔖 增加今日头条的授权登陆。注:该版为beta版,因头条开发者申请的问题,并未经过测试。待测试通过后正式发布release版
This commit is contained in:
@@ -71,6 +71,7 @@ public class AuthorizationFactory {
|
||||
AuthorizationFactory.register(AuthSource.LINKEDIN, new LinkedinAuthorization());
|
||||
AuthorizationFactory.register(AuthSource.MICROSOFT, new MicrosoftAuthorization());
|
||||
AuthorizationFactory.register(AuthSource.MI, new MiAuthorization());
|
||||
AuthorizationFactory.register(AuthSource.TOUTIAO, new ToutiaoAuthorization());
|
||||
loader = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.zhyd.oauth.authorization;
|
||||
|
||||
import me.zhyd.oauth.config.AuthConfig;
|
||||
import me.zhyd.oauth.utils.UrlBuilder;
|
||||
|
||||
/**
|
||||
* 今日头条授权
|
||||
*
|
||||
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
||||
* @version 1.0
|
||||
* @since 1.8
|
||||
*/
|
||||
public class ToutiaoAuthorization implements Authorization {
|
||||
|
||||
@Override
|
||||
public String getAuthorizeUrl(AuthConfig config) {
|
||||
return UrlBuilder.getToutiaoAuthorizeUrl(config.getClientId(), config.getRedirectUri());
|
||||
}
|
||||
}
|
||||
@@ -561,6 +561,35 @@ public enum ApiUrl {
|
||||
public String refresh() {
|
||||
return "https://account.xiaomi.com/oauth2/token";
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 今日头条
|
||||
*/
|
||||
TOUTIAO {
|
||||
@Override
|
||||
public String authorize() {
|
||||
return "https://open.snssdk.com/auth/authorize";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String accessToken() {
|
||||
return "https://open.snssdk.com/auth/token";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String userInfo() {
|
||||
return "https://open.snssdk.com/data/user_profile";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String revoke() {
|
||||
throw new AuthException(ResponseStatus.UNSUPPORTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String refresh() {
|
||||
throw new AuthException(ResponseStatus.UNSUPPORTED);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,5 +26,6 @@ public enum AuthSource {
|
||||
DOUYIN,
|
||||
LINKEDIN,
|
||||
MICROSOFT,
|
||||
MI
|
||||
MI,
|
||||
TOUTIAO
|
||||
}
|
||||
|
||||
54
src/main/java/me/zhyd/oauth/model/AuthToutiaoErrorCode.java
Normal file
54
src/main/java/me/zhyd/oauth/model/AuthToutiaoErrorCode.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package me.zhyd.oauth.model;
|
||||
|
||||
/**
|
||||
* 今日头条授权登录时的异常状态码
|
||||
*
|
||||
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
||||
* @version 1.0
|
||||
* @since 1.8
|
||||
*/
|
||||
public enum AuthToutiaoErrorCode {
|
||||
EC0(0, "接口调用成功"),
|
||||
EC1(1, "API配置错误,未传入Client Key"),
|
||||
EC2(2, "API配置错误,Client Key错误,请检查是否和开放平台的ClientKey一致"),
|
||||
EC3(3, "没有授权信息"),
|
||||
EC4(4, "响应类型错误"),
|
||||
EC5(5, "授权类型错误"),
|
||||
EC6(6, "client_secret错误"),
|
||||
EC7(7, "authorize_code过期"),
|
||||
EC8(8, "指定url的scheme不是https"),
|
||||
EC9(9, "接口内部错误,请联系头条技术"),
|
||||
EC10(10, "access_token过期"),
|
||||
EC11(11, "缺少access_token"),
|
||||
EC12(12, "参数缺失"),
|
||||
EC13(13, "url错误"),
|
||||
EC21(21, "域名与登记域名不匹配"),
|
||||
EC999(999, "未知错误,请联系头条技术"),
|
||||
;
|
||||
|
||||
private int code;
|
||||
private String desc;
|
||||
|
||||
AuthToutiaoErrorCode(int code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static AuthToutiaoErrorCode getErrorCode(int errorCode) {
|
||||
AuthToutiaoErrorCode[] errorCodes = AuthToutiaoErrorCode.values();
|
||||
for (AuthToutiaoErrorCode code : errorCodes) {
|
||||
if (code.getCode() == errorCode) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
return EC999;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
67
src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java
Normal file
67
src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java
Normal file
@@ -0,0 +1,67 @@
|
||||
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.*;
|
||||
import me.zhyd.oauth.utils.UrlBuilder;
|
||||
|
||||
/**
|
||||
* 今日头条登录
|
||||
*
|
||||
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
||||
* @version 1.5
|
||||
* @since 1.5
|
||||
*/
|
||||
public class AuthToutiaoRequest extends BaseAuthRequest {
|
||||
|
||||
public AuthToutiaoRequest(AuthConfig config) {
|
||||
super(config, AuthSource.TOUTIAO);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuthToken getAccessToken(String code) {
|
||||
String accessTokenUrl = UrlBuilder.getToutiaoAccessTokenUrl(config.getClientId(), config.getClientSecret(), code);
|
||||
HttpResponse response = HttpRequest.get(accessTokenUrl).execute();
|
||||
JSONObject object = JSONObject.parseObject(response.body());
|
||||
|
||||
if (object.containsKey("error_code")) {
|
||||
throw new AuthException(AuthToutiaoErrorCode.getErrorCode(object.getIntValue("error_code")).getDesc());
|
||||
}
|
||||
|
||||
return AuthToken.builder()
|
||||
.accessToken(object.getString("access_token"))
|
||||
.expireIn(object.getIntValue("expires_in"))
|
||||
.openId(object.getString("open_id"))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
||||
HttpResponse userResponse = HttpRequest.get(UrlBuilder.getToutiaoUserInfoUrl(config.getClientId(), authToken.getAccessToken())).execute();
|
||||
|
||||
JSONObject userProfile = JSONObject.parseObject(userResponse.body());
|
||||
|
||||
if (userProfile.containsKey("error_code")) {
|
||||
throw new AuthException(AuthToutiaoErrorCode.getErrorCode(userProfile.getIntValue("error_code")).getDesc());
|
||||
}
|
||||
|
||||
JSONObject user = userProfile.getJSONObject("data");
|
||||
|
||||
boolean isAnonymousUser = user.getIntValue("uid_type") == 14;
|
||||
String anonymousUserName = "匿名用户";
|
||||
|
||||
return AuthUser.builder()
|
||||
.uuid(user.getString("uid"))
|
||||
.username(isAnonymousUser ? anonymousUserName : user.getString("screen_name"))
|
||||
.nickname(isAnonymousUser ? anonymousUserName : user.getString("screen_name"))
|
||||
.avatar(user.getString("avatar_url"))
|
||||
.remark(user.getString("description"))
|
||||
.gender(AuthUserGender.getRealGender(user.getString("gender")))
|
||||
.token(authToken)
|
||||
.source(AuthSource.TOUTIAO)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -92,6 +92,10 @@ public class UrlBuilder {
|
||||
private static final String MI_USER_INFO_PATTERN = "{0}?clientId={1}&token={2}";
|
||||
private static final String MI_REFRESH_TOKEN_PATTERN = "{0}?client_id={1}&client_secret={2}&redirect_uri={3}&refresh_token={4}&grant_type=refresh_token";
|
||||
|
||||
private static final String TOUTIAO_ACCESS_TOKEN_PATTERN = "{0}?client_key={1}&client_secret={2}&code={3}&grant_type=authorize_code";
|
||||
private static final String TOUTIAO_USER_INFO_PATTERN = "{0}?client_key={1}&access_token={2}";
|
||||
private static final String TOUTIAO_AUTHORIZE_PATTERN = "{0}?client_key={1}&redirect_uri={2}&state={3}&response_type=code&auth_only=1&display=0";
|
||||
|
||||
/**
|
||||
* 获取githubtoken的接口地址
|
||||
*
|
||||
@@ -776,4 +780,38 @@ public class UrlBuilder {
|
||||
public static String getMiRefreshUrl(String clientId, String clientSecret, String redirectUrl, String refreshToken) {
|
||||
return MessageFormat.format(MI_REFRESH_TOKEN_PATTERN, ApiUrl.MI.refresh(), clientId, clientSecret, redirectUrl, refreshToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取今日头条授权地址
|
||||
*
|
||||
* @param clientId 今日头条 应用的Client ID
|
||||
* @param redirectUrl 今日头条 应用授权成功后的回调地址
|
||||
* @return full url
|
||||
*/
|
||||
public static String getToutiaoAuthorizeUrl(String clientId, String redirectUrl) {
|
||||
return MessageFormat.format(TOUTIAO_AUTHORIZE_PATTERN, ApiUrl.TOUTIAO.authorize(), clientId, redirectUrl, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取今日头条 token的接口地址
|
||||
*
|
||||
* @param clientId 今日头条 应用的Client ID
|
||||
* @param clientSecret 今日头条 应用的Client Secret
|
||||
* @param code 今日头条 授权前的code,用来换token
|
||||
* @return full url
|
||||
*/
|
||||
public static String getToutiaoAccessTokenUrl(String clientId, String clientSecret, String code) {
|
||||
return MessageFormat.format(TOUTIAO_ACCESS_TOKEN_PATTERN, ApiUrl.TOUTIAO.accessToken(), clientId, clientSecret, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取今日头条用户详情的接口地址
|
||||
*
|
||||
* @param clientId 今日头条 应用的client_key
|
||||
* @param token token
|
||||
* @return full url
|
||||
*/
|
||||
public static String getToutiaoUserInfoUrl(String clientId, String token) {
|
||||
return MessageFormat.format(TOUTIAO_USER_INFO_PATTERN, ApiUrl.TOUTIAO.userInfo(), clientId, token);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user