第三方登入是現在的應用、網站很常用的功能。能夠提高使用者註冊率,簡化登入流程,充分利用各大門戶的使用者資源。
最近的工作中涉及到了第三方登入的功能,為了方便日後使用,將此部分功能進行了簡單的封裝。
##OAuth2
oauth2是當前主流的第三方授權協議。通過此協議呼叫可以獲取到服務提供方的使用者各種詳細資訊,呼叫提供方的API介面實現各種功能。
OAuth2的第三方登入認證流程主要分為三步: ####1、帶領使用者訪問認證url 提供給使用者,或者轉發至提供方的認證URL,並指定一個回撥介面,使用者進行授權之後,服務提供方會告知回撥介面,進行下一步操作
####2、通過code獲取access_token 服務提供方會向回撥介面傳遞一個code,呼叫指定的API,可以使用此code獲取一個access_token,這是授權的證據,使用此token可以呼叫服務提供商的各種介面
####3、使用access_token獲取使用者資訊 完成授權後,使用此token可以獲取使用者的賬號,暱稱,id,頭像等各種資訊。
##實現: 為了統一呼叫,首先封裝了一個抽象類:
public abstract class OAuth2 {
public static final String QQ = "qq";
public static final String SINA = "sina";
public static final String WECHAT = "wechat";
public static OAuth2 getOAuthTool(String company){
switch(company){
case QQ:
return new QQOauth2();
case SINA:
return new SinaOAuth2();
case WECHAT:
return new WechatOAuth2();
}
return null;
}
public abstract JSONObject getAccessToken(String code);
public abstract JSONObject getUser(String access_token, String oid);
public abstract String getAuthUrl();
}
複製程式碼
抽象類中提供了一個工廠方法,可見我已經實現了QQ,新浪微博和微信的第三方登入功能。根據不同的引數就可以返回不同的例項。
下面以微信登入為例說明一下實現:
public class WechatOAuth2 extends OAuth2{
static String client_ID = "wxxxxxxxxxxxxxx";
static String client_SERCRET = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
static String redirect_URI = "http://www.thinkool.com.cn/oauth/signin";
/*----------------------------Oauth介面--------------------------------------*/
@Override
public JSONObject getAccessToken(String code) {
Map<String,Object> objectMap
= new HashMap<>();
objectMap.put("client_id", client_ID);
objectMap.put("client_secret", client_SERCRET);
objectMap.put("grant_type", "authorization_code");
objectMap.put("code", code);
objectMap.put("redirect_uri", redirect_URI);
//
String url =
"https://api.weixin.qq.com/sns/oauth2/access_token?grant_type=authorization_code&"+
"appid="+client_ID+
"&secret="+client_SERCRET+
"&code="+code+
"&state="+"wechat"+"&redirect_uri="+redirect_URI;
try {
//access_token & openid
return HttpUtil.get(url);
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
@Override
public JSONObject getUser(String access_token,String oid) {
String getuser = "https://api.weixin.qq.com/sns/userinfo?"+
"access_token="+access_token+
"&openid="+oid;
JSONObject user = null;
try {
user = HttpUtil.get(getuser);
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// user.put("openid",oid);
//openid & nickname & headimgurl
System.out.println(user);
return user;
}
@Override
public String getAuthUrl() {
return "https://open.weixin.qq.com/connect/qrconnect" +
"?appid="+ client_ID.trim() +
"&redirect_uri="+ redirect_URI.trim()
+ "&response_type=code" + "&state=wechat" +"&scope=snsapi_login";
}
}
複製程式碼
首先getAuthUrl方法完成第一步,拼寫一個認證字串,並引導使用者訪問以完成授權。
getAccessToken方法完成第二步,通過返回的code獲取到一個access_token。
getUser方法完成第三部,通過獲取到的access_token呼叫介面以獲取使用者的詳細資訊。
##其他事項
####1、此實現依賴於阿里的開源Json庫fastjson ####2、不同的提供方的呼叫流程不完全一致。 微信和新浪的第一步授權提供了此使用者的openid,在呼叫時直接使用access_token和openid就可以獲取使用者的詳細資訊。QQ的授權則沒有提供openid,需要進行一步獲取openid,才能使用openid獲取到使用者的詳細資訊。