zoukankan      html  css  js  c++  java
  • QQ互联Oauth2.0认证测试

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

    如此。

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

    来个网站应用吧!

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

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

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

    示例:

      

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

    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());
        }
    }
    每一步脚印都要扎得深一点!
  • 相关阅读:
    Entity Framework开源了
    动态执行超过4000个字符的SQL
    微软针对Access提供了免费的SQL Server移植工具——SSMA
    网络采集库NCrawler
    使用WinSCP软件在windows和Linux中进行文件传输
    Open Source C# (Mono Compatible) Library for Sending Push Notifications To iOS (iPhone/iPad APNS), Android (C2DM), Windows Phone Apps
    Mono 2.11.3 发布包含微软的 Entity Framework
    谷歌发布 AngularJS 1.0,允许扩展HTML语法
    Accord.NET Framework
    CentOS源码编译安装Nginx和tcp_proxy module
  • 原文地址:https://www.cnblogs.com/bloodthirsty/p/4110822.html
Copyright © 2011-2022 走看看