您的位置:首页 > 其它

QQ第三方登陆及同步内容到腾讯微博,腾讯空间,朋友网

2015-01-14 15:18 274 查看
一、开发前准备工作

1 进入http://connect.qq.com进行登陆,然后点击网站接入(根据需求,如果需要移动应用接入点击移动应用接入)。下列例子为网站接入。

2 创建应用页面中,将鼠标放在”验证”按钮上,会弹出一个小窗口,将要复制的内容复制下来放在你网站的首页对应位置,然后点击”开始验证”按钮



二、开发

1 将该代码放入你网站登陆页面
<a href='https://graph.qq.com/oauth2.0/authorize?client_id=YOUR_APPID&response_type=code&scope=all&status=LEO&redirect_uri=YOUR_REDIRECT_URI'>
<img border="0"alt="QQ登录" src="http://qzonestyle.gtimg.cn/qzone/vas/opensns/res/img/Connect_logo_1.png"></img>
</a>


按钮图片下载官方地址:

http://wiki.connect.qq.com/%E7%BD%91%E7%AB%99%E5%89%8D%E7%AB%AF%E9%A1%B5%E9%9D%A2%E8%A7%84%E8%8C%83#1..E4.BD.BF.E7.94.A8.E8.85.BE.E8.AE.AF.E6.8F.90.E4.BE.9B.E7.9A.84.E6.A0.87.E5.87.86.E2.80.9CQQ.E7.99.BB.E5.BD.95.E2.80.9D.E6.A0.87.E8.AF.86

注意修改a标签中href里面client_id后面的值改为你应用的appid,status的值可以改成你想设置的值,可以用于验证是否来你应用的请求。redirect_uri是你的回调地址,该回调地址用于成功登陆后的操作。Scope的值还可以是其他值,scope不填时默认为get_user_info。具体请参考官方:http://wiki.connect.qq.com/api%E5%88%97%E8%A1%A8

2 进入到你网址的QQ登陆页面,点击QQ登陆图标,如果出现回调地址不合法的提示,请参考官方进行回调地址修改,官方地址如下:

http://wiki.connect.qq.com/%E5%9B%9E%E8%B0%83%E5%9C%B0%E5%9D%80%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E5%8F%8A%E4%BF%AE%E6%94%B9%E6%96%B9%E6%B3%95

一切顺畅出现如下页面:



3 获取access_token和openid方法我写在回调action中,具体代码如下:

package com.wingo.action.config;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.wingo.util.CommonUtil;

import com.wingo.util.ConfigUtil;

public class TencentLoginAction {

private static Logger log = LoggerFactory.getLogger(TencentLoginAction.class);

HttpServletRequest request = ServletActionContext.getRequest();

HttpServletResponse response = ServletActionContext.getResponse();

public String execute(){

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

request.setAttribute("code", code);

/* 获取access_token

* 成功后返回信息格式access_token=BA03E5Bxxxxxx950&expires_in=7776000&refresh_token=8972279xxxxxxF8752F

* 一般access_token有效期是三个月

*/

String parames = "grant_type=authorization_code&client_id="+ConfigUtil.CLIENT_ID+"&client_secret="+ConfigUtil.CLIENT_SECRET+"&code="+code+"&redirect_uri="+ConfigUtil.REDIRECT_URI;

String access_result = CommonUtil.httpsRequest(ConfigUtil.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("登陆页面");

} catch (IOException e) {

e.printStackTrace();

}

}else {

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

request.setAttribute("access_token", access_token);

/* 获取openid

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

*/

String open_id = CommonUtil.httpsRequest(ConfigUtil.OPENID_URL, "GET", access_token);

request.setAttribute("openid", 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("登陆页面");

} catch (IOException e) {

e.printStackTrace();

}

}else {

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

request.setAttribute("myOpenId", openId);

//TODO 我们可以将access_token与openid一起存入数据库

/*发布一条不带图片的腾讯微博

*(注意:微博内容140个汉子,即420字节。若在此处@好友,需要填写好友的微博账号而非昵称)

* 默认返回json格式

* 如:{"data":{"id":"466544017145386","time":1421201332},"errcode":0,"msg":"ok","ret":0,"seqid":6104013246275818942}

* 其中ret为0表示成功

*/

parames = access_token+"&oauth_consumer_key="+ConfigUtil.CLIENT_ID+"&openid="+openId+"&content=LEO测试发布一条不带图片的腾讯微博";

String reslut = CommonUtil.httpsRequest(ConfigUtil.ADD_T_URL, "POST", parames);

request.setAttribute("reslut", reslut);

}

}

return "test";

}

}

上面相关的工具类代码如下:

package com.wingo.util;

import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.UnsupportedEncodingException;

import java.net.ConnectException;

import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

import javax.net.ssl.SSLContext;

import javax.net.ssl.SSLSocketFactory;

import javax.net.ssl.TrustManager;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

CommonUtil工具类

/**

* 通用工具类

* @author 李欣桦

* @date 2014-11-21下午9:10:30

*/

public class CommonUtil {

private static Logger log = LoggerFactory.getLogger(CommonUtil.class);

/**

* 发送https请求

*

* @param requestUrl 请求地址

* @param requestMethod 请求方式(GET、POST)

* @param outputStr 提交的数据

* @return 返回微信服务器响应的信息

*/

public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {

try {

// 创建SSLContext对象,并使用我们指定的信任管理器初始化

TrustManager[] tm = { new MyX509TrustManager() };

SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");

sslContext.init(null, tm, new java.security.SecureRandom());

// 从上述SSLContext对象中得到SSLSocketFactory对象

SSLSocketFactory ssf = sslContext.getSocketFactory();

URL url = new URL(requestUrl);

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

conn.setSSLSocketFactory(ssf);

conn.setDoOutput(true);

conn.setDoInput(true);

conn.setUseCaches(false);

// 设置请求方式(GET/POST)

conn.setRequestMethod(requestMethod);

conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");

// 当outputStr不为null时向输出流写数据

if (null != outputStr) {

OutputStream outputStream = conn.getOutputStream();

// 注意编码格式

outputStream.write(outputStr.getBytes("UTF-8"));

outputStream.close();

}

// 从输入流读取返回内容

InputStream inputStream = conn.getInputStream();

InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");

BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

String str = null;

StringBuffer buffer = new StringBuffer();

while ((str = bufferedReader.readLine()) != null) {

buffer.append(str);

}

// 释放资源

bufferedReader.close();

inputStreamReader.close();

inputStream.close();

inputStream = null;

conn.disconnect();

return buffer.toString();

} catch (ConnectException ce) {

log.error("连接超时:{}", ce);

} catch (Exception e) {

log.error("https请求异常:{}", e);

}

return null;

}

public static String urlEncodeUTF8(String source){

String result = source;

try {

result = java.net.URLEncoder.encode(source,"utf-8");

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

return result;

}

}

ConfigUtil工具类:

package com.wingo.util;

public class ConfigUtil {

//应用appid

public static final String CLIENT_ID= "101XXXXXX18";

//应用appsecret

public static final String CLIENT_SECRET = "21aXXXXXXXXXXXX86";

//授权成功后的回调地址

public static final String REDIRECT_URI = "http://loginXXXXXXXXte.action";

//获取token的url(GET)获取到access_token后有效期三个月

public static final String TOKEN_URL = "https://graph.qq.com/oauth2.0/token";

//获取openid的url(GET)

public static final String OPENID_URL = "https://graph.qq.com/oauth2.0/me";

//发布一条不带图片的腾讯微博(POST)

public static final String ADD_T_URL = "https://graph.qq.com/t/add_t";

}

package com.wingo.util;

import java.security.cert.CertificateException;

import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

MyX509TrustManager工具类:

/**

* 信任管理器

* @author 李欣桦

* @date 2014-11-21下午9:15:08

*/

public class MyX509TrustManager implements X509TrustManager {

// 检查客户端证书

public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

}

// 检查服务器端证书

public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

}

// 返回受信任的X509证书数组

public X509Certificate[] getAcceptedIssuers() {

return null;

}

}

上面回调方法中获取access_token,openid 时也可以根据自己的需要传其他参数。

官方地址:http://wiki.connect.qq.com/%E4%BD%BF%E7%94%A8authorization_code%E8%8E%B7%E5%8F%96access_token

除了发布腾讯微博,还可以利用其他api获取你想要的功能。api列表官方地址:http://wiki.connect.qq.com/api%E5%88%97%E8%A1%A8。具体使用方法可以参考上面回调地址中发布腾讯微博的代码。

4 利用腾讯开发平台组件可以分享内容到QQ空间和朋友网(在弹出页面,用户也可以选择是否分享到腾讯微博)。该组件不需要用户授权也可使用,当没有腾讯用户是登录状态时(相对腾讯网),弹出的分享界面会让分享用户先登录。官方网址:http://connect.qq.com/intro/share

例子如下:
<div>
<script type="text/javascript">
(function(){
var p = {
url:location.href,
showcount:'1',/*是否显示分享总数,显示:'1',不显示:'0' ,分享总数是以上面的url值统计的总数*/
desc:'我的分享理由',/*默认分享理由(可选),140汉字以内*/
summary:'这是我的摘要',/*分享摘要(可选)*/
title:'这是我的标题',/*分享标题(可选)*/
site:'分享来源:LEO测试',/*分享来源 如:腾讯网(可选)*/
pics:'http://img4.imgtn.bdimg.com/it/u=3654516648,56113462&fm=23&gp=0.jpg', /*分享图片的路径(可选)*/
style:'202',/*分享按钮的样式,下面的宽高亦为分享按钮的宽高*/
width:105,
height:31
};
var s = [];
for(var i in p){
s.push(i + '=' + encodeURIComponent(p[i]||''));
}
document.write(['<a version="1.0" class="qzOpenerDiv" href="http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?',s.join('&'),'" target="_blank">分享</a>'].join(''));
})();
</script>
</div>
<script type="text/javascript" src="<%=basePath%>/common/js/jquery-1.7.js"></script>
<script src="http://qzonestyle.gtimg.cn/qzone/app/qzlike/qzopensl.js#jsdate=20111201" charset="utf-8"></script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: