该代码包含请求第三方平台验证用户信息的逻辑,部分代码为我自己开发时使用的代码,需根据自己的实际情况进行替换,详细的流程可以查阅第三方的开发者平台。
package com.dg.util;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.dg.business.util.HttpClientUtil;
import com.dg.config.ConfigManager;
import com.dg.constant.JmePropertyFileNamespaceConst;
import com.dg.emum.AppleVerifyUserTypeEnum;
import com.dg.key.FacebookConfigKey;
import com.dg.key.GoogleConfigKey;
import com.dg.key.LineConfigKey;
import com.dg.key.SignInWithAppleConfigKey;
import com.dg.key.UserConfigKey;
import com.dg.log.LoggerManage;
import com.dg.resource.entity.AppleLoginEntity;
import com.dg.resource.tuple.TwoTuple;
/**
* @author:DingGuang
* @Date: 2022/3/2 18:10
*/
public class ThirdPartyLoginUtil {
private final static Logger log = LoggerManage.getLogger();
public final static String FACEBOOK_DEBUG_TOKEN_BASE_URL = "https://graph.facebook.com/debug_token";
public final static String LINE_TOKEN_OAUTH_URL = "https://api.line.me/oauth2/v2.1/verify?access_token=%s";
public final static String LINE_GET_USER_PROFILE_URL = "https://api.line.me/v2/profile";
public final static String BEARER_ACCESS_TOKEN = "Bearer %s";
public static TwoTuple<Boolean, String> checkAppleToken(
String authorizationCode, String userStrToVerify) {
// 获取苹果登录所需配置
String clientId = getAppleProperty(SignInWithAppleConfigKey.CLIENT_ID);
String teamId = getAppleProperty(SignInWithAppleConfigKey.TEAM_ID);
String kid = getAppleProperty(SignInWithAppleConfigKey.KID);
String privateKey = getAppleProperty(
SignInWithAppleConfigKey.PRIVATE_KEY);
// 生成clientSecret
String clientSecret = SignInWithAppleUtil.generateClientSecret(kid,
teamId, clientId, privateKey);
// false 使用代理
int agent = Integer.parseInt(ConfigManager
.getProperty(UserConfigKey.APPLE_AUTH_TOKEN_AGENT_SWITCH, "0"));
boolean useLocal = agent == 0;
// 获取服务端根据授权码生成的user,授权码只能使用一次
AppleLoginEntity appleLoginEntity = SignInWithAppleUtil
.generateAppleUser(clientId, clientSecret, authorizationCode,
AppleVerifyUserTypeEnum.AUTH_CODE, useLocal);
String generateUserStr = appleLoginEntity.getAppleUser();
if (StringUtil.isNullOrEmpty(generateUserStr)
|| !generateUserStr.equals(userStrToVerify)) {
return new TwoTuple<>(false, "");
}
return new TwoTuple<>(true, userStrToVerify);
}
/**
* 检测facebook的登录
*
* @param inputToken
* @return
*/
public static TwoTuple<Boolean, String> checkFacebookToken(
String inputToken) {
String clientId = ConfigManager.getPropertyWithNamespace(
JmePropertyFileNamespaceConst.FACEBOOK,
FacebookConfigKey.CLIENT_ID, "");
String clientSecret = ConfigManager.getPropertyWithNamespace(
JmePropertyFileNamespaceConst.FACEBOOK,
FacebookConfigKey.CLIENT_SECRET, "");
String url = FACEBOOK_DEBUG_TOKEN_BASE_URL + "?input_token="
+ inputToken + "&access_token=" + clientId + "%7C"
+ clientSecret;
int socketTimeout = NumberUtil
.parseOrDefault(ConfigManager.getPropertyWithNamespace(
JmePropertyFileNamespaceConst.FACEBOOK,
FacebookConfigKey.SOCKET_TIMEOUT), 0);
int connectionTimeout = NumberUtil
.parseOrDefault(ConfigManager.getPropertyWithNamespace(
JmePropertyFileNamespaceConst.FACEBOOK,
FacebookConfigKey.CONNECTION_TIMEOUNT), 0);
String result = HttpClientUtil.get(url, new HashMap<>(), socketTimeout,
connectionTimeout);
if (!StringUtil.isNullOrEmpty(result)) {
JsonNode jsonNode = JacksonUtil.json2JsonNode(result);
String dataKey = "data";
if (jsonNode.has(dataKey)) {
JsonNode dataObj = jsonNode.get(dataKey);
String appId = dataObj.get("app_id").asText();
boolean isValid = dataObj.get("is_valid").booleanValue();
if (appId.equals(clientId) && isValid) {
String facebookUserId = dataObj.get("user_id").asText();
return new TwoTuple<>(true, facebookUserId);
}
}
}
return new TwoTuple<>(false, "");
}
/**
* 检测google的登录
*
* @param accessToken
* @return
*/
public static TwoTuple<Boolean, String> checkGoogleToken(
String accessToken) {
String clientId = ConfigManager.getPropertyWithNamespace(
JmePropertyFileNamespaceConst.GOOGLE, GoogleConfigKey.CLIENT_ID,
"");
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(
new NetHttpTransport(), GsonFactory.getDefaultInstance())
.setAudience(Collections.singletonList(clientId))
.build();
try {
GoogleIdToken idToken = verifier.verify(accessToken);
if (idToken != null) {
GoogleIdToken.Payload payload = idToken.getPayload();
String userIdentify = payload.getSubject();
return new TwoTuple<>(true, userIdentify);
} else {
return new TwoTuple<>(false, "");
}
} catch (Exception e) {
log.error("checkGoogleToken error:", e);
return new TwoTuple<>(false, "");
}
}
/**
* 检测LINE登录
*
* @param accessToken
* @return
*/
public static TwoTuple<Boolean, String> checkLineToken(String accessToken) {
String url = String.format(LINE_TOKEN_OAUTH_URL, accessToken);
int socketTimeout = NumberUtil.parseOrDefault(ConfigManager
.getPropertyWithNamespace(JmePropertyFileNamespaceConst.LINE,
LineConfigKey.SOCKET_TIMEOUT),
3000);
int connectionTimeout = NumberUtil.parseOrDefault(ConfigManager
.getPropertyWithNamespace(JmePropertyFileNamespaceConst.LINE,
LineConfigKey.CONNECTION_TIMEOUNT),
3000);
// 请求验证token的接口
String result = HttpClientUtil.get(url, new HashMap<>(), socketTimeout,
connectionTimeout);
if (!StringUtil.isNullOrEmpty(result)) {
JsonNode jsonNode = JacksonUtil.json2JsonNode(result);
String clientIdKey = "client_id";
String expiresKey = "expires_in";
if (jsonNode.has(clientIdKey) && jsonNode.has(expiresKey)) {
long expiresIn = jsonNode.get(expiresKey).asLong();
if (expiresIn > 0) {
String clientIdValue = jsonNode.get(clientIdKey).asText();
String clientId = ConfigManager.getPropertyWithNamespace(
JmePropertyFileNamespaceConst.LINE,
LineConfigKey.CLIENT_ID, "");
if (clientId.equals(clientIdValue)) {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", String
.format(BEARER_ACCESS_TOKEN, accessToken));
// token验证成功后请求获取LINE的用户信息
String profileStr = HttpClientUtil.get(
LINE_GET_USER_PROFILE_URL, new HashMap<>(),
headers, socketTimeout, connectionTimeout);
if (!StringUtil.isNullOrEmpty(profileStr)) {
JsonNode userProfile = JacksonUtil
.json2JsonNode(profileStr);
String userIdKey = "userId";
if (userProfile.has(userIdKey)) {
String userId = userProfile.get(userIdKey)
.asText();
return new TwoTuple<>(true, userId);
}
}
}
}
}
}
return new TwoTuple<>(false, "");
}
private static String getAppleProperty(String key) {
return ConfigManager.getPropertyWithNamespace(
JmePropertyFileNamespaceConst.APPLE, key, "");
}
}