首页 > 代码库 > QQ互联Oauth2.0认证测试

QQ互联Oauth2.0认证测试

我不太喜欢讲原理,喜欢按照应用流程一步步完成一个测试项目,然后掉过头来看原理。

如此。

首先,我们得建一个应用,这无可厚非。

来个网站应用吧!

填写基本信息时,有个网站地址,我们填写一个自己所维护的外部网站页面地址。

在HEAD标签里按照提示,嵌入验证代码,并加以验证。

回调地址填写相应的域名。

示例:

  

在新建的web项目里新加一个配置文件如下:

app_ID = ********app_KEY = *************************redirect_URI = http://www.******************.tk/Qqtest4SDK/afterlogin.doscope = 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_addrbaseURL = https://graph.qq.com/getUserInfoURL = https://graph.qq.com/user/get_user_infoaccessTokenURL = https://graph.qq.com/oauth2.0/tokenauthorizeURL = https://graph.qq.com/oauth2.0/authorizegetOpenIDURL = 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());    }}

 

QQ互联Oauth2.0认证测试