经过两天的努力 已经成功将QQ登录集成到了
宅男宅女 上。感谢腾讯提供的帮助文档,和关键时刻给的技术支持。我的网站是asp.net写的,有需要的网友可以联系我。 呵呵。(尽管是垃圾站,只要你愿意,又有什么关系呢?)
QQ Oauth 只提供PHP的接入demo ,针对 ASP.net 的只有一个网友开发的SDK包,下载地址还老打不开,后来我从CSDN上下载了一个,看了以后感觉太复杂了,我个人感觉做这么个小事情不需要搞个SDK出来,不如自己按帮助文档去写,这样自己写的方法灵活性就高一些,于是就按文档学习开发。其实文档写得很清晰,耐心一看就明白了。
不讲太多的郁闷的过程了,直接说解决办法。
办这个事情主要要知道下面几个事情。
两个重点(如下):
第一个重点:请求Token的步骤,
1:请求未授权的临时token。请求成功以后会转到QQ登录页面。
2:请求已授权的临时token。登陆成功以后获得。
3:请求已授权的Access token。
第二个重点:签名的算法。
签名的值计算有一个指定的规则,请参考腾讯开放社区帮助文档,这是最 好的资料。
注意点:
没有申请APPID和APPKEY的先去申请。
传递的每一参数都要URLENcode,注意是每一个,包括动态生成的签名。
参数之间是有顺序的,是升序排列的,无论有多少个,都要排序。
各个步骤之间是有关联的,下一步的提交往往需要上一步的返回参数。
我采取的文档结构:
总共三个文件 ,非常简单。
一个放在APPcode下面的类。用来发送请求和接待参数。
两个前台页面,主要是对类的调用。
将上面的代码放到APPcode 下面,按步骤写你的前台页面就行了。
我也做过PHP开发,我个人认为asp.net做这个要比PHP简单明了,不知道为什么腾讯不给出asp.net方面的demo。难道是对微软的歧视?!呵呵。
QQ Oauth 只提供PHP的接入demo ,针对 ASP.net 的只有一个网友开发的SDK包,下载地址还老打不开,后来我从CSDN上下载了一个,看了以后感觉太复杂了,我个人感觉做这么个小事情不需要搞个SDK出来,不如自己按帮助文档去写,这样自己写的方法灵活性就高一些,于是就按文档学习开发。其实文档写得很清晰,耐心一看就明白了。
不讲太多的郁闷的过程了,直接说解决办法。
办这个事情主要要知道下面几个事情。
两个重点(如下):
第一个重点:请求Token的步骤,
1:请求未授权的临时token。请求成功以后会转到QQ登录页面。
2:请求已授权的临时token。登陆成功以后获得。
3:请求已授权的Access token。
第二个重点:签名的算法。
签名的值计算有一个指定的规则,请参考腾讯开放社区帮助文档,这是最 好的资料。
注意点:
没有申请APPID和APPKEY的先去申请。
传递的每一参数都要URLENcode,注意是每一个,包括动态生成的签名。
参数之间是有顺序的,是升序排列的,无论有多少个,都要排序。
各个步骤之间是有关联的,下一步的提交往往需要上一步的返回参数。
我采取的文档结构:
总共三个文件 ,非常简单。
一个放在APPcode下面的类。用来发送请求和接待参数。
两个前台页面,主要是对类的调用。
下面把类的代码完全贴出,你知要一看见类,就知道怎么写前台页面了,很简单。
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Net;
using System.Security.Cryptography;
using System.IO;
using System.Collections;
/// <summary>
/// QQOAuth 的摘要说明
/// 版权:城记网(114box.com),请保留版权
/// 作者:JXY
/// Q Q:281773404
/// 日 期:2011-08-20
/// </summary>
public class QQOAuth
{
public static string appid = "21****";
public static string appkey = "427ca17***************************de";
public static string questadd = "http://openapi.qzone.qq.com/oauth/qzoneoauth_request_token";
/// <summary>
/// 请求临时的Token
/// </summary>
/// <returns></returns>
public static string GetTempToken()
{
string myrandomnum = oauthnonce(); //随机数
string unixtime = GenerateTimeStamp();//时间戳
string token_parameter = "oauth_consumer_key=" + appid + "&oauth_nonce=" + myrandomnum + "&oauth_signature_method=HMAC-SHA1&oauth_timestamp=" + unixtime + "&oauth_version=1.0";
string code_token_parameter = "GET&" + Uri.EscapeDataString(questadd) + "&" + Uri.EscapeDataString(token_parameter);
string miyuetemp = appkey + "&";
string signvl = ToBase64hmac(code_token_parameter, miyuetemp);
string url = string.Format("{0}?{1}{2}{3}",questadd, token_parameter, "&oauth_signature=", Uri.EscapeDataString(signvl));
string QQreturnstr = RequestUrl(url);
return QQreturnstr;
}
/// <summary>
/// 请求ACCESS的Token
/// </summary>
/// <param name="oauth_token">获得授权临时Token的时候获得的参数</param>
/// <param name="oauth_vericode">获得授权临时Token的时候获得的验证代码</param>
/// <param name="oauth_token_secret">获得授权临时Token的时候获得的密钥</param>
/// <returns>返回ACCess Token</returns>
public static string GetAccessToken(string oauth_token, string oauth_vericode, string oauth_token_secret)
{
string thisquestadd = "http://openapi.qzone.qq.com/oauth/qzoneoauth_access_token";
string myrandomnum = oauthnonce(); //随机数
string unixtime = GenerateTimeStamp();//时间戳
string token_parameter = "oauth_consumer_key=" + appid + "&oauth_nonce=" + myrandomnum + "&oauth_signature_method=HMAC-SHA1&oauth_timestamp=" + unixtime + "&oauth_token=" + oauth_token + "&oauth_vericode=" + oauth_vericode + "&oauth_version=1.0";
string code_token_parameter = "GET&" + Uri.EscapeDataString(thisquestadd) + "&" + Uri.EscapeDataString(token_parameter);
string miyuetemp = appkey + "&" + oauth_token_secret;
string signvl = ToBase64hmac(code_token_parameter, miyuetemp);
string url = string.Format("{0}?{1}{2}{3}",thisquestadd, token_parameter, "&oauth_signature=", Uri.EscapeDataString(signvl));
string QQreturnstr = RequestUrl(url);
return QQreturnstr;
}
/// <summary>
/// 获得用户信息的API
/// </summary>
/// <param name="oauth_token">Access token 请求是返回的</param>
/// <param name="openid">Access token 请求是返回的 openid</param>
/// <param name="oauth_token_secret">Access token 请求是返回的动态密钥</param>
/// <returns>XML</returns>
public static string GetQQUserInfo(string oauth_token, string openid, string oauth_token_secret)
{
string thisquestadd = "http://openapi.qzone.qq.com/user/get_user_info";
string myrandomnum = oauthnonce(); //随机数
string unixtime = GenerateTimeStamp();//时间戳
string token_parameter = "format=xml&oauth_consumer_key=" + appid + "&oauth_nonce=" + myrandomnum + "&oauth_signature_method=HMAC-SHA1&oauth_timestamp=" + unixtime + "&oauth_token=" + oauth_token + "&oauth_version=1.0&openid="+openid;
string code_token_parameter = "GET&" + Uri.EscapeDataString(thisquestadd) + "&" + Uri.EscapeDataString(token_parameter);
string miyuetemp = appkey + "&" + oauth_token_secret;
string signvl = ToBase64hmac(code_token_parameter, miyuetemp);
string url = string.Format("{0}?{1}{2}{3}", thisquestadd, token_parameter, "&oauth_signature=", Uri.EscapeDataString(signvl));
string QQreturnstr = RequestUrl(url);
return QQreturnstr;
}
#region 服务方法
/// <summary>
/// hmacSha1算法加密并返回ToBase64String
/// </summary>
/// <param name="strText">签名参数字符串</param>
/// <param name="strKey">密钥</param>
/// <returns>返回一个签名参数值</returns>
public static string ToBase64hmac(string strText, string strKey)
{
HMACSHA1 myHMACSHA1 = new HMACSHA1(Encoding.UTF8.GetBytes(strKey));
byte[] byteText = myHMACSHA1.ComputeHash(Encoding.UTF8.GetBytes(strText));
return System.Convert.ToBase64String(byteText);
}
/// <summary>
/// 请求指定url地址并返回结果
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static string RequestUrl(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.MaximumAutomaticRedirections = 3;
request.Timeout = 0x2710;
Stream responseStream = ((HttpWebResponse)request.GetResponse()).GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string str = reader.ReadToEnd();
reader.Close();
responseStream.Close();
return str;
}
/// <summary>
/// Base64编码,此方法的功能同方法ToBase64hmac
/// 目前内有使用该方法
/// </summary>
/// <returns></returns>
public static string HMACSHA1(string consumer_secret, string oauth_token_secret, string signaturebasestring)
{
HMACSHA1 hmacsha1 = new HMACSHA1();
hmacsha1.Key = Encoding.ASCII.GetBytes(consumer_secret + "&" + oauth_token_secret);
byte[] dataBuffer = System.Text.Encoding.ASCII.GetBytes(signaturebasestring);
byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);
string signature = Convert.ToBase64String(hashBytes);
return signature;
}
/// <summary>
/// 时间戳返回unix时间戳
/// </summary>
/// <returns></returns>
public static string GenerateTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
/// <summary>
/// 随机字符串
/// </summary>
/// <returns></returns>
public static string oauthnonce()
{
int number;
string checkCode = String.Empty;
Random random = new Random();
for (int i = 0; i < 9; i++)
{
number = random.Next(0, 9);
checkCode += number.ToString();
}
return checkCode;
}
/// <summary>
/// 将认证获得的参数简单转化为哈希表
/// </summary>
/// <param name="varstr">获得参数的字符串</param>
/// <returns></returns>
public static Hashtable Str2Hash(string varstr)
{
Hashtable myhash = new Hashtable();
if (varstr.Trim() != string.Empty)
{
string[] temparr = varstr.Split('&');
foreach (string onevarstr in temparr)
{
string[] onevararr=onevarstr.Split('=');
myhash.Add(onevararr[0], onevararr[1]);
}
return myhash;
}
else
{
return null;
}
}
#endregion
}
将上面的代码放到APPcode 下面,按步骤写你的前台页面就行了。
我也做过PHP开发,我个人认为asp.net做这个要比PHP简单明了,不知道为什么腾讯不给出asp.net方面的demo。难道是对微软的歧视?!呵呵。
实例下载地址: http://download.csdn.net/detail/hongsejiaozhu/3677410