我不太喜歡講原理,喜歡按照應用流程一步步完成一個測試項目,而後掉過頭來看原理。html
如此。web
首先,咱們得建一個應用,這無可厚非。json
來個網站應用吧!後端
填寫基本信息時,有個網站地址,咱們填寫一個本身所維護的外部網站頁面地址。app
在HEAD標籤裏按照提示,嵌入驗證代碼,並加以驗證。dom
回調地址填寫相應的域名。jsp
示例:工具
在新建的web項目裏新加一個配置文件以下:post
app_ID = ******** app_KEY = ************************* redirect_URI = http://www.******************.tk/Qqtest4SDK/afterlogin.do scope = get_user_info,add_topic,add_one_blog,add_album,upload_pic,list_album,add_share,check_page_fans,add_t,add_pic_t,del_t,get_repost_list,get_info,get_other_info,get_fanslist,get_idollist,add_idol,del_ido,get_tenpay_addr baseURL = https://graph.qq.com/ getUserInfoURL = https://graph.qq.com/user/get_user_info accessTokenURL = https://graph.qq.com/oauth2.0/token authorizeURL = https://graph.qq.com/oauth2.0/authorize getOpenIDURL = https://graph.qq.com/oauth2.0/me
這裏的redirect_URI是在oauth2.0認證時調用的地址,必須爲有效地址,且爲同項目下的,我建一個Servlet對應該請求。測試
咱們訪問網站地址(並無作特殊的處理),默認將跳轉到本地的index.jsp,jsp的頭部以前已經說過,須要添加先關驗證<meta>標籤
body部分:
<center> <!-- 測試登錄受權 --> <a href="/Qqtest4SDK/login.do"><img src="/Qqtest4SDK/img/qq_login.png" /></a> </center>
後端Servlet處理請求:
public class IndexServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html;charset=utf-8"); try { String reUrl =new Oauth().getAuthorizeURL(request); response.sendRedirect(reUrl); } catch (QQConnectException e) { e.printStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { doGet(request, response); } }
這裏咱們須要瞭解下Oauth2.0的相關認證,Eclipse market下載安裝JadClipse反編譯工具.
Oauth2.0:
構造請求(PC):
Step1:獲取 Authorization Code
Get方式:
https://graph.qq.com/oauth2.0/token
參數:
response_type 固定爲code、client_id爲appid、redirect_uri 受權成功後callbackURL、state:client端的狀態值
public String getAuthorizeURL(ServletRequest request) throws QQConnectException { String state = RandomStatusGenerator.getUniqueState(); ((HttpServletRequest) request).getSession().setAttribute( "qq_connect_state", state); String scope = QQConnectConfig.getValue("scope"); if ((scope != null) && (!(scope.equals("")))) { return getAuthorizeURL("code", state, scope); } return QQConnectConfig.getValue("authorizeURL").trim() + "?client_id=" + QQConnectConfig.getValue("app_ID").trim() + "&redirect_uri=" + QQConnectConfig.getValue("redirect_URI").trim() + "&response_type=" + "code" + "&state=" + state; }
Step2:經過 Authorization Code獲取令牌Access Token:
受權成功後,解析響應信息,獲取authorization code及原始的state:
private String[] extractionAuthCodeFromUrl(String url) throws QQConnectException { if (url == null) { throw new QQConnectException("you pass a null String object"); } Matcher m = Pattern.compile("code=(\\w+)&state=(\\w+)&?").matcher(url); String authCode = ""; String state = ""; if (m.find()) { authCode = m.group(1); state = m.group(2); } return new String[] { authCode, state }; }
封裝信息,並POST請求獲取Access Token:
public AccessToken getAccessTokenByRequest(ServletRequest request) throws QQConnectException { String queryString = ((HttpServletRequest) request).getQueryString(); if (queryString == null) { return new AccessToken(); } String state = (String) ((HttpServletRequest) request).getSession() .getAttribute("qq_connect_state"); if ((state == null) || (state.equals(""))) { return new AccessToken(); } String[] authCodeAndState = extractionAuthCodeFromUrl(queryString); String returnState = authCodeAndState[1]; String returnAuthCode = authCodeAndState[0]; AccessToken accessTokenObj = null; if ((returnState.equals("")) || (returnAuthCode.equals(""))) { accessTokenObj = new AccessToken(); } else if (!(state.equals(returnState))) { accessTokenObj = new AccessToken(); } else accessTokenObj = new AccessToken(this.client.post( QQConnectConfig.getValue("accessTokenURL"), new PostParameter[] { new PostParameter("client_id", QQConnectConfig .getValue("app_ID")), new PostParameter("client_secret", QQConnectConfig .getValue("app_KEY")), new PostParameter("grant_type", "authorization_code"), new PostParameter("code", returnAuthCode), new PostParameter("redirect_uri", QQConnectConfig .getValue("redirect_URI")) }, Boolean .valueOf(false))); return accessTokenObj; }
有了令牌,咱們就能夠根據令牌獲取openid,有了openid咱們才能夠調用接口。
那麼,如何獲取openid呢?
Step3:獲取Openid
請求地址:https://graph.qq.com/oauth2.0/me
參數 :access_token
Get方式:
private String getUserOpenID(String accessToken) throws QQConnectException { String openid = ""; String jsonp = this.client.get( QQConnectConfig.getValue("getOpenIDURL"), new PostParameter[] { new PostParameter("access_token", accessToken) }).asString(); Matcher m = Pattern.compile("\"openid\"\\s*:\\s*\"(\\w+)\"").matcher( jsonp); if (m.find()) openid = m.group(1); else { throw new QQConnectException("server error!"); } return openid; }
Step4:調用OpenAPI
以get_user_info接口爲例:
https://graph.qq.com/user/get_user_info?access_token=YOUR_ACCESS_TOKEN&oauth_consumer_key=YOUR_APP_ID&openid=YOUR_OPENID
很簡單,構造UserInfo 繼承自維護access token和openid的父類,新增返回用戶信息UserInfoBean的方法:
在方法裏請求以上url並封裝響應結果json信息便可:
public class UserInfo extends QQConnect { private static final long serialVersionUID = -6124397423510235640L; public UserInfo(String token, String openID) { super(token, openID); } private UserInfoBean getUserInfo(String openid) throws QQConnectException { return new UserInfoBean(this.client.get( QQConnectConfig.getValue("getUserInfoURL"), new PostParameter[] { new PostParameter("openid", openid), new PostParameter("oauth_consumer_key", QQConnectConfig .getValue("app_ID")), new PostParameter("access_token", this.client .getToken()), new PostParameter("format", "json") }).asJSONObject()); } public UserInfoBean getUserInfo() throws QQConnectException { return getUserInfo(this.client.getOpenID()); } }