您的位置:首页 > 编程语言 > Java开发

第三方登录 QQ WEIBO

2015-04-26 23:25 302 查看
①准备工作
               I--注册QQ互联账号 -->在管理中心注册为开发者 -->创建应用 -->获取应用APP ID





  II--在nat123注册应用域名



     III--下载包 
<!--qq互联-->

        <dependency>

            <groupId>commons-codec</groupId>

            <artifactId>commons-codec</artifactId>

            <version>1.3</version>

        </dependency>

        <dependency>

            <groupId>commons-httpclient</groupId>

            <artifactId>commons-httpclient</artifactId>

            <version>3.1</version>

        </dependency>



②开始实践
------------------------------------------------------------------------------------------------------------------------
1>js版本(pc上)
------------------------------------------------------------------------------------------------------------------------

详情请见:http://connect.qq.com/intro/login/jssdk-demo
例子(网站请求页和回调地址页是同一个页面)

-------------------------------------------------------------------------------------------------------------
2>sdk_client版本(mobile)【使用java后台本地代理进行跨域请求】【jsonp也可以跨域请求】
          疑问:请求成功后返回的数据时html格式?非json格式
-------------------------------------------------------------------------------------------------------------

<%@ page language="java" pageEncoding="UTF-8" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

    <title>Client Flow Example</title>

    <script type="text/javascript" src="resources/js/jquery-2.0.3.min.js"></script>

</head>

<body>

<a href="https://graph.qq.com/oauth2.0/authorize?response_type=token&client_id=101201540&redirect_uri=http://jiasi.nat123.net/index.jsp&scope=get_user_info">qq</a>

<%--*http://jiasi.nat123.net/index.jsp?#access_token=C34A4EB530203E213DD9F5A5E9B891E6&expires_in=7776000*--%>

<a href="https://graph.qq.com/oauth2.0/me?access_token=C34A4EB530203E213DD9F5A5E9B891E6">获取openId</a>

<%--*callback( {"client_id":"101201540","openid":"AFBEA3786C12A923F66BAD7D2F87DFCC"} ); *--%>

<a href="https://graph.qq.com/user/get_user_info?access_token=C34A4EB530203E213DD9F5A5E9B891E6&oauth_consumer_key=101201540&openid=AFBEA3786C12A923F66BAD7D2F87DFCC">获取信息</a>

<%--用户信息--%>

<hr/>

<a href="https://graph.qq.com/oauth2.0/authorize?response_type=token&client_id=101201540&redirect_uri=http://jiasi.nat123.net/index.jsp&scope=get_user_info">腾讯QQ登录</a>

<img id="userImg"/>

<button type="submit" onclick="clickQQ();"> QQ登录</button>

<span id="userName"></span>

<script type="text/javascript">
var accessToken = window.location.hash.substring(1);//获取路径中的access_token

    $.ajax({

        type: 'GET',

        url: 'https://graph.qq.com/oauth2.0/me?'+accessToken,

        async: false,

        dataType: "jsonp",

        jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)

        jsonpCallback:"callback",

        success: function(o){

            console.log(o);//o就是上面提到的返回包

            $.ajax({

                type: 'POST',

                url:"/login.do",

                data:{url: 'https://graph.qq.com/user/get_user_info?'+accessToken+'&oauth_consumer_key=101201540&openid='+o.openid},

                async: false,

                dataType: "json",

                success: function(e){

                    alert(e.nickname);

                    console.log(e);

                    $("#userImg").attr("src",e.figureurl_qq_2);

                }

            });

        }

    });

</script>

</body>

</html>

============
public class LoginServlet extends HttpServlet{

    @Override

    protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("inter..................");

        /*req.getRequestDispatcher("/WEB-INF/success.jsp").forward(req, resp);*/

        String url = request.getParameter("url");

        System.out.println(url);

        HttpClient httpClient = new HttpClient();

        // 创建GET方法的实例

        GetMethod getMethod = new GetMethod(url);

        // 使用系统提供的默认的恢复策略

        getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,

                new DefaultHttpMethodRetryHandler());

        try {

            // 执行getMethod

            int statusCode = httpClient.executeMethod(getMethod);

            if (statusCode != 200) {

                System.err.println("Method failed: "

                        + getMethod.getStatusLine());

            }

            // 读取内容

            byte[] responseBody = getMethod.getResponseBody();

            String Msg = getMethod.getResponseBodyAsString().trim();

            System.out.println("message--------------"+Msg);

            // 处理内容

        } catch (HttpException e) {

            // 发生致命的异常,可能是协议不对或者返回的内容有问题

            System.out.println();

            e.printStackTrace();

        } catch (IOException e) {

            // 发生网络异常

            e.printStackTrace();

        } finally {

            // 释放连接

            getMethod.releaseConnection();

       
13609
}

    }

QQ第三方登陆
http://wiki.open.qq.com/wiki/website/JS_SDK使用说明
网站接入流程--qq登陆
http://wiki.open.qq.com/wiki/website/网站接入流程
===============
QQ分享空间
分享QQ好友:
http://wiki.connect.qq.com/com-tencent-tauth-tencent-sharetoqq
------------------------=---
分享到各网站的js代码
http://www.xunhuweb.com/blog/416

-----------------------------------------------------------------------------------------------------------------------------------
后期修改                           js版QQ登陆改为手机版本
-----------------------------------------------------------------------------------------------------------------------------------

第一种方案:页面上获取access_token和openid,后台处理用户数据
1、页面部署
+++++++++第一种情况++++++++++
----在放置qq  button的页面引入js库
    <script type="text/javascript" src="http://qzonestyle.gtimg.cn/qzone/openapi/qc_loader.js" data-appid="101201540" data-redirecturi="http://jiasi.nat123.net/ole-mobile/index.html" charset="utf-8"
></script>

---添加qq按钮和按钮样式
 <span id="qqButton" ></span>
QC.Login({

                btnId : "qqButton",//插入按钮的html标签id

                size : "B_M",//按钮尺寸

                scope : "get_user_info",//展示授权,全部可用授权可填 all

                display : "mobile"//应用场景,可选

            });
---回调页面获取access_token和openid并发送请求到后台处理获得用户数据
var accessToken = window.location.hash.substring(1);//获取路径中的access_token

            if(accessToken) {

                $.ajax({

                    type: 'GET',

                    url: 'https://graph.qq.com/oauth2.0/me?' + accessToken,

                    async: false,

                    dataType: "jsonp",

                    jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)

                    jsonpCallback: "callback",

                    success: function (o) {

                        alert(o.openid);

                        $.ajax({

                            type: 'POST',

                            url: "/member/qq_login",

                            data: {url: 'https://graph.qq.com/user/get_user_info?' + accessToken + '&oauth_consumer_key=101201540&openid=' + o.openid},

                            async: false,

                            dataType: "json",

                            success: function (e) {

                                alert(e);

                                alert(e.msg);

                                if (e.success) {

                                }

                            }

                        });

                    }

                });

            }
+++++++++第二种情况++++++++++
tip①不需要再页面引入js库,没有qq按钮的样式

<span id="qq_click" href="#" style="color:red;">
<img src="img/qq.png"/>
</span>


注意使用<a>标签链接的形式没办法打开页面
所以使用html可识别的标签并使用jquery 点击事件打开网页

$("#qq_click").click(function(){
window.location.href = "https://graph.qq.com/oauth2.0/authorize?response_type=token&display=mobile&client_id=101201540&scope=get_user_info&redirect_uri=http://jiasi.nat123.net/ole-mobile/qq_login.html";
});


为了把QQ登录和正常登录的页面解耦,于是单独把QQ登录的处理过程另外放到一个页面去处理

<script type="text/javascript" src="js/jquery.min-2.1.1.js"></script>

<script type="text/javascript">

var accessToken = window.location.hash.substring(1);//获取路径中的access_token
if (accessToken) {
$.ajax({
type: 'GET',
url: 'https://graph.qq.com/oauth2.0/me?' + accessToken,
async: false,
dataType: "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback: "callback",
success: function (o) {
$.ajax({
type: 'POST',
url: "/ole-web/m/member/qq_login",
data: {url: 'https://graph.qq.com/user/get_user_info?' + accessToken + '&oauth_consumer_key=101201540&openid=' + o.openid},
async: false,
dataType: "json",
success: function (e) {
alert(e.msg);
if (e.success) {

window.localStorage.setItem("member_info", e.data.memberId + '|' +
e.data.token + '|' +
e.data.nickname + '|' +
e.data.portrait + '|' +
e.data.balance);

window.location.href = "/ole-mobile/index.html#memberview";
}

}
});
}
});
}
</script>


2、后台处理用户数据

@Transactional
public ThirdpartyMember getUserInfoFromQQ(String url/*HttpServletRequest request*/) {
log.info("QQ第三方登录");
//        String url = request.getParameter("url");
System.out.println("url:"+url);
/*获取openid*/
String[] params = url.split("&");
String openid = params[OPENID_AND_VALUE_INDEX].substring(OPENID_INDEX);

HttpClient httpClient = new HttpClient();
// 创建GET方法的实例
GetMethod getMethod = new GetMethod(url);
// 使用系统提供的默认的恢复策略
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler());
try {
// 执行getMethod
int statusCode = httpClient.executeMethod(getMethod);
if (statusCode != 200) {
System.err.println("Method failed: "
+ getMethod.getStatusLine());
}
// 读取内容
byte[] responseBody = getMethod.getResponseBody();
String msg = getMethod.getResponseBodyAsString().trim();
if (msg != null && !msg.equals("")) {
System.out.println("message----" + msg);
String[] s = msg.split(",");
StringBuffer sb = new StringBuffer();
for (String s1 : s) {
if (s1.contains("nickname")) {
sb.append(s1.split(":")[NICKNAME_INDEX].replace("\"", ""));
} else if (s1.contains("figureurl")) {
sb.append(",");
sb.append(s1.substring(PORTRAIT_INDEX));
}
if(s1.contains("figureurl_qq_1")) {
sb.append(",");
System.out.println("----====qq--"+s1);
sb.append(s1.substring(24));
System.out.println("24---"+s1.substring(24));
break;
}
}
String nickname = sb.toString().split(",")[0];
String portrait = sb.toString().split(",")[1];
String qq_portrait = sb.toString().split(",")[2];
System.out.println("...qq_pro--"+qq_portrait);
/*保存第三方登录的用户信息 memberThirdParty 和 member 实体*/
Member member= saveThirdparty(openid, nickname, portrait, ThirdParty.QQ);
ThirdpartyMember thirdpartyMember = new ThirdpartyMember();
thirdpartyMember.setNickname(nickname);
thirdpartyMember.setPortrait(portrait);
thirdpartyMember.setOrigin(ThirdParty.QQ);
thirdpartyMember.setUsername(member.getUsername());
thirdpartyMember.setMemberId(member.getId());
System.out.println("username......"+member.getUsername());
thirdpartyMember.setPassword("third");
System.out.println("memberservice--------------"+member.getPassword());
return thirdpartyMember;
}
ResponseEntity<HttpEntity> hi = new ResponseEntity(responseBody, HttpStatus.OK);

System.out.println("hi----"+hi.toString());
// 处理内容
//            return new ResponseEntity(responseBody, HttpStatus.OK);
} catch (HttpException e) {
// 发生致命的异常,可能是协议不对或者返回的内容有问题
System.out.println();
e.printStackTrace();
//            return new ResponseEntity("Please check your provided http address!", HttpStatus.BAD_REQUEST);
} catch (IOException e) {
// 发生网络异常
e.printStackTrace();
//            return new ResponseEntity("Time out!", HttpStatus.BAD_GATEWAY);
} finally {
// 释放连接
getMethod.releaseConnection();
}
return null;
}


第二种方案 页面点击QQ登录  完全交给后台获取access_token、openid、处理用户数据

1、页面
用jquery构造触发点击事件 GET请求至qqRequest

2、后台处理
这是在Controller层的,可以调用上面提到的getUserInfoFromQQ

/* @RequestMapping(value = "/qqRequest",method = RequestMethod.GET)

    public String qqRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {

        String code = request.getParameter("code");

        request.setAttribute("code", code);

        System.out.println("...................");

        *//* 获取access_token*//*

        String parames = "grant_type=authorization_code&client_id="+ CommonUtil.APP_ID +"&client_secret="+ CommonUtil.APP_KEY +"&code="+code+"&redirect_uri=" + CommonUtil.REDIRECT_URI;

        String access_result = HttpRequestUtil.httpsRequest(CommonUtil.REQUEST_TOKEN_URL, "GET", parames);

        if(access_result.contains("callback")){

        *//*当返回的access_token是callback( {"error":100019,"error_description":"code to access token error"} )类似的数据;

        * 表示获取access_token失败,需要返回点击QQ登陆页面让用户重新登陆授权

        *//*

            try {

                response.sendRedirect("/ole-mobile/index2.html");

            } catch (IOException e) {

                e.printStackTrace();

            }

        }else {

            String access_token = access_result.split("&")[0];

            System.out.println("access_token="+access_token);

            *//* 获取openid

             * 成功后返回信息格式:callback( {"client_id":"10xxxxx18","openid":"DDxxxxxxxxxxx587"} );

             *//*

            String open_id = HttpRequestUtil.httpsRequest(CommonUtil.REQUEST_OPENID_URL, "GET", access_token);

            System.out.println("open_id="+open_id);

            if(open_id.contains("error")){

                *//*当返回的open_id是callback( {"error":100007,"error_description":"param access token is wrong or lost "} );类似的数据;

                 * 表示获取open_id失败,需要返回点击QQ登陆页面让用户重新登陆授权

                 *//*

                try {

                    response.sendRedirect("/ole-mobile/index2.html");

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }else {

                String openId = open_id.substring(open_id.indexOf("openid")+9, open_id.lastIndexOf("\""));

                String url = "https://graph.qq.com/user/get_user_info?"+access_token+"&oauth_consumer_key=101201540&openid=" + openId;

                System.out.println("url:"+url);

                ThirdpartyMember thirdpartyMember = memberService.getUserInfoFromQQ(url);

                System.out.println("thirdpartyMember---"+thirdpartyMember.getUsername());

                if (thirdpartyMember != null) {

                    Map<String, ThirdpartyMember> map = new HashMap<>();

                    map.put("thirdQuery", thirdpartyMember);

                    //用户第三方登录的会员名字和密码 正常登录 保存token

                    System.out.println("login success!");

                    //登录成功,保存改用户token

                    Token memberToken = new Token();

                    memberToken.setMemberId(thirdpartyMember.getMemberId());

                    memberToken.setToken(UUID.randomUUID().toString());

                    tokenRepository.save(memberToken);

                    //查询该会员账户余额

                    BigDecimal balance = accountService.findBalanceByMemberId(thirdpartyMember.getMemberId());

                    MemberBean memberBean = new MemberBean();

                    memberBean.setMobile(thirdpartyMember.getUsername());

                    memberBean.setNickname(thirdpartyMember.getNickname());

                    memberBean.setPortrait(thirdpartyMember.getPortrait());

                    memberBean.setMemberId(thirdpartyMember.getMemberId());

                    memberBean.setToken(memberToken.getToken());

                    memberBean.setBalance(balance);

                    System.out.println("json="+JSON.toJSONString(memberBean));

                    return new Message(true,"login success!",memberBean).toJson();

                }

            }

        }

        return new Message(true,"login fail!").toJson();

    }*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java web oauth