您的位置:首页 > 编程语言 > ASP

asp.net网站整合QQ一键登录

2012-10-17 11:36 393 查看
对于有会员功能的网站来讲,嵌入QQ一键登录,可以借助QQ庞大的用户群体提升网站的用户体验,留住更多的用户。示例网站www.1189.tv ,ASP.NET网站整合QQ一键登录流程如下:

1、先去QQ官方看下详细的步骤http://wiki.opensns.qq.com/wiki/%E3%80%90QQ%E7%99%BB%E5%BD%95%E3%80%91%E7%BD%91%E7%AB%99%E6%8E%A5%E5%85%A5,网站程序实现主要流程是:获取并存储access
token以及openid

(1)access token用来判断用户在本网站上的登录状态,具有3个月有效期,网站需实现防过期策略,并在过期后提示用户再次授权;

(2)openid是此网站上唯一对应用户身份的标识,网站可将此ID进行存储便于用户下次登录时辨识其身份,或将其与用户在网站上的原有账号进行绑定。

需要用到的类代码

using System.Text;
using System.Net;
using System.Security.Cryptography;
using System.IO;
using System.Collections;
/// <summary>
/// QQOAuth 的摘要说明
/// </summary>
public class QQOAuth
{
public static string appid = "你申请的";
public static string appkey = "你申请的";

#region 请求ACCESS的Token
/// <summary>
/// 请求ACCESS的Token
/// </summary>
/// <param name="oauth_token_secret">获得授权临时Token的时候获得的密钥</param>
/// <returns>返回ACCess Token</returns>
public static string GetAccessToken(string oauth_code)
{
string thisquestadd = "https://graph.qq.com/oauth2.0/token";
string token_parameter = "grant_type=authorization_code&client_id=" + appid + "&client_secret=" + appkey + "&code=" + oauth_code + "&redirect_uri=http://www.1189.tv";
string url = string.Format("{0}?{1}",thisquestadd, token_parameter);
string QQreturnstr = RequestUrl(url);
return QQreturnstr;
}
#endregion

#region 请求ACCESS的OpenID
/// <summary>
/// 请求ACCESS的OpenID
/// </summary>
/// <param name="Access Token">使用Access Token来获取用户的OpenID</param>
/// <returns>返回OpenID</returns>
public static string GetAccessOpenID(string AccessToken)
{
string thisquestadd = "https://graph.qq.com/oauth2.0/me";
string token_parameter = "access_token="+AccessToken;
string url = string.Format("{0}?{1}", thisquestadd, token_parameter);
string QQreturnstr = RequestUrl(url);
return QQreturnstr;
}
#endregion

#region 获得用户信息的API
/// <summary>
/// 获得用户信息的API
/// </summary>
/// <param name="oauth_token">Access token 请求是返回的</param>
/// <param name="openid">Access token 请求是返回的 openid</param>
/// <returns>XML</returns>
public static string GetQQUserInfo(string oauth_token, string openid)
{
string QQreturnstr = RequestUrl("https://graph.qq.com/user/get_user_info?access_token="+oauth_token+"&oauth_consumer_key="+appid+"&openid="+openid);
return QQreturnstr;
}
#endregion

#region 服务方法
/// <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>
/// 将认证获得的参数简单转化为哈希表
/// </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

}


实现这个功能的时候中间遇到腾讯返回的json数据格式取值的问题,可以用如下类来解决

using System;
using System.Collections.Generic;
using System.Text;

/// <summary>
/// 用于构建属性值的回调
/// </summary>
/// <param name="Property"></param>
public delegate void SetProperties(JsonObject Property);

/// <summary>
/// JsonObject属性值类型
/// </summary>
public enum JsonPropertyType
{
String,
Object,
Array,
Number,
Bool,
Null
}

/// <summary>
/// JSON通用对象
/// </summary>
public class JsonObject
{
private Dictionary<String, JsonProperty> _property;

public JsonObject()
{
this._property = null;
}

public JsonObject(String jsonString)
{
this.Parse(ref jsonString);
}

public JsonObject(SetProperties callback)
{
if (callback != null)
{
callback(this);
}
}

/// <summary>
/// Json字符串解析
/// </summary>
/// <param name="jsonString"></param>
private void Parse(ref String jsonString)
{
int len = jsonString.Length;
if (String.IsNullOrEmpty(jsonString) || jsonString.Substring(0, 1) != "{" || jsonString.Substring(jsonString.Length - 1, 1) != "}")
{
throw new ArgumentException("传入文本不符合Json格式!" + jsonString);
}
Stack<Char> stack = new Stack<char>();
Stack<Char> stackType = new Stack<char>();
StringBuilder sb = new StringBuilder();
Char cur;
bool convert = false;
bool isValue = false;
JsonProperty last = null;
for (int i = 1; i <= len - 2; i++)
{
cur = jsonString[i];
if (cur == '}')
{
;
}
if (cur == ' ' && stack.Count == 0)
{
;
}
else if ((cur == '\'' || cur == '\"') && !convert && stack.Count == 0 && !isValue)
{
sb.Length = 0;
stack.Push(cur);
}
else if ((cur == '\'' || cur == '\"') && !convert && stack.Count > 0 && stack.Peek() == cur && !isValue)
{
stack.Pop();
}
else if ( (cur == '[' || cur == '{') && stack.Count == 0)
{
stackType.Push(cur == '[' ? ']' : '}');
sb.Append(cur);
}
else if ((cur == ']' || cur == '}') && stack.Count == 0 && stackType.Peek() == cur)
{
stackType.Pop();
sb.Append(cur);
}
else if (cur == ':' && stack.Count == 0 && stackType.Count == 0 && !isValue)
{
last = new JsonProperty();
this[sb.ToString()] = last;
isValue = true;
sb.Length = 0;
}
else if (cur == ',' && stack.Count == 0 && stackType.Count == 0)
{
if (last != null)
{

String temp = sb.ToString();
last.Parse(ref temp);
}
isValue = false;
sb.Length = 0;
}
else
{
sb.Append(cur);
}
}
if (sb.Length > 0 && last != null && last.Type == JsonPropertyType.Null)
{
String temp = sb.ToString();
last.Parse(ref temp);
}
}

/// <summary>
/// 获取属性
/// </summary>
/// <param name="PropertyName"></param>
/// <returns></returns>
public JsonProperty this[String PropertyName]
{
get
{
JsonProperty result = null;
if (this._property != null && this._property.ContainsKey(PropertyName))
{
result = this._property[PropertyName];
}
return result;
}
set
{
if (this._property == null)
{
this._property = new Dictionary<string, JsonProperty>(StringComparer.OrdinalIgnoreCase);
}
if (this._property.ContainsKey(PropertyName))
{
this._property[PropertyName] = value;
}
else
{
this._property.Add(PropertyName, value);
}
}
}

/// <summary>
/// 通过此泛型函数可直接获取指定类型属性的值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="PropertyName"></param>
/// <returns></returns>
public virtual T Properties<T>(String PropertyName) where T : class
{
JsonProperty p = this[PropertyName];
if (p != null)
{
return p.GetValue<T>();
}
return default(T);
}

/// <summary>
/// 获取属性名称列表
/// </summary>
/// <returns></returns>
public String[] GetPropertyNames()
{
if (this._property == null)
return null;
String[] keys = null;
if (this._property.Count > 0)
{
keys = new String[this._property.Count];
this._property.Keys.CopyTo(keys, 0);
}
return keys;
}

/// <summary>
/// 移除一个属性
/// </summary>
/// <param name="PropertyName"></param>
/// <returns></returns>
public JsonProperty RemoveProperty(String PropertyName)
{
if (this._property != null && this._property.ContainsKey(PropertyName))
{
JsonProperty p = this._property[PropertyName];
this._property.Remove(PropertyName);
return p;
}
return null;
}

/// <summary>
/// 是否为空对象
/// </summary>
/// <returns></returns>
public bool IsNull()
{
return this._property == null;
}

public override string ToString()
{
return this.ToString("");
}

/// <summary>
/// ToString...
/// </summary>
/// <param name="format">格式化字符串</param>
/// <returns></returns>
public virtual string ToString(String format)
{
if (this.IsNull())
{
return "{}";
}
else
{
StringBuilder sb = new StringBuilder();
foreach (String key in this._property.Keys)
{
sb.Append(",");
sb.Append(key).Append(": ");
sb.Append(this._property[key].ToString(format));

}
if (this._property.Count > 0)
{
sb.Remove(0, 1);
}
sb.Insert(0, "{");
sb.Append("}");
return sb.ToString();
}
}
}

/// <summary>
/// JSON对象属性
/// </summary>
public class JsonProperty
{
private JsonPropertyType _type;
private String _value;
private JsonObject _object;
private List<JsonProperty> _list;
private bool _bool;
private double _number;

public JsonProperty()
{
this._type = JsonPropertyType.Null;
this._value = null;
this._object = null;
this._list = null;
}

public JsonProperty(Object value)
{
this.SetValue(value);
}

public JsonProperty(String jsonString)
{
this.Parse(ref jsonString);
}

/// <summary>
/// Json字符串解析
/// </summary>
/// <param name="jsonString"></param>
public void Parse(ref String jsonString)
{
if (String.IsNullOrEmpty(jsonString))
{
this.SetValue(null);
}
else
{
string first = jsonString.Substring(0, 1);
string last = jsonString.Substring(jsonString.Length - 1, 1);
if (first == "[" && last == "]")
{
this.SetValue(this.ParseArray(ref jsonString));
}
else if (first == "{" && last=="}")
{
this.SetValue(this.ParseObject(ref jsonString));
}
else if ((first == "'" || first == "\"") && first == last)
{
this.SetValue( this.ParseString(ref jsonString));
}
else if (jsonString == "true" || jsonString == "false")
{
this.SetValue(jsonString == "true" ? true : false);
}
else if (jsonString == "null")
{
this.SetValue(null);
}
else
{
double d = 0;
if (double.TryParse(jsonString, out d))
{
this.SetValue(d);
}
else
{
this.SetValue(jsonString);
}
}
}
}

/// <summary>
/// Json Array解析
/// </summary>
/// <param name="jsonString"></param>
/// <returns></returns>
private List<JsonProperty> ParseArray(ref String jsonString)
{
List<JsonProperty> list = new List<JsonProperty>();
int len = jsonString.Length;
StringBuilder sb = new StringBuilder();
Stack<Char> stack = new Stack<char>();
Stack<Char> stackType = new Stack<Char>();
bool conver = false;
Char cur;
for (int i = 1; i <= len - 2; i++)
{
cur = jsonString[i];
if (Char.IsWhiteSpace(cur) && stack.Count == 0)
{
;
}
else if ((cur == '\'' && stack.Count == 0 && !conver && stackType.Count == 0) || (cur == '\"' && stack.Count == 0 && !conver && stackType.Count == 0))
{
sb.Length = 0;
sb.Append(cur);
stack.Push(cur);
}
else if (cur == '\\' && stack.Count > 0 && !conver)
{
sb.Append(cur);
conver = true;
}
else if (conver == true)
{
conver = false;

if (cur == 'u')
{
sb.Append(new char[] { cur, jsonString[i + 1], jsonString[i + 2], jsonString[i + 3] });
i += 4;
}
else
{
sb.Append(cur);
}
}
else if ((cur == '\'' || cur == '\"') && !conver && stack.Count>0 && stack.Peek() == cur && stackType.Count == 0)
{
sb.Append(cur);
list.Add(new JsonProperty(sb.ToString()));
stack.Pop();
}else if( (cur == '[' || cur == '{' ) && stack.Count==0 )
{
if (stackType.Count == 0)
{
sb.Length = 0;
}
sb.Append( cur);
stackType.Push((cur == '[' ? ']' : '}'));
}
else if ((cur == ']' || cur == '}') && stack.Count == 0 && stackType.Count>0 && stackType.Peek() == cur)
{
sb.Append(cur);
stackType.Pop();
if (stackType.Count == 0)
{
list.Add(new JsonProperty(sb.ToString()));
sb.Length = 0;
}

}
else if (cur == ',' && stack.Count == 0 && stackType.Count == 0)
{
if (sb.Length > 0)
{
list.Add(new JsonProperty(sb.ToString()));
sb.Length = 0;
}
}
else
{
sb.Append(cur);
}
}
if (stack.Count > 0 || stackType.Count > 0)
{
list.Clear();
throw new ArgumentException("无法解析Json Array对象!");
}
else if (sb.Length > 0)
{
list.Add(new JsonProperty(sb.ToString()));
}
return list;
}

/// <summary>
/// Json String解析
/// </summary>
/// <param name="jsonString"></param>
/// <returns></returns>
private String ParseString(ref String jsonString)
{
int len = jsonString.Length;
StringBuilder sb = new StringBuilder();
bool conver = false;
Char cur;
for (int i = 1; i <= len - 2; i++)
{
cur = jsonString[i];
if (cur == '\\' && !conver)
{
conver = true;
}
else if (conver == true)
{
conver = false;
if (cur == '\\' || cur == '\"' || cur == '\'' || cur == '/')
{
sb.Append(cur);
}
else
{
if (cur == 'u')
{
String temp = new String(new char[] { cur, jsonString[i + 1], jsonString[i + 2], jsonString[i + 3] });
sb.Append((char)Convert.ToInt32(temp, 16));
i += 4;
}
else
{
switch (cur)
{
case 'b':
sb.Append('\b');
break;
case 'f':
sb.Append('\f');
break;
case 'n':
sb.Append('\n');
break;
case 'r':
sb.Append('\r');
break;
case 't':
sb.Append('\t');
break;
}
}
}
}
else
{
sb.Append(cur);
}
}
return sb.ToString();
}

/// <summary>
/// Json Object解析
/// </summary>
/// <param name="jsonString"></param>
/// <returns></returns>
private JsonObject ParseObject(ref String jsonString)
{
return new JsonObject(jsonString);
}

/// <summary>
/// 定义一个索引器,如果属性是非数组的,返回本身
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public JsonProperty this[int index]
{
get
{
JsonProperty r = null;
if (this._type == JsonPropertyType.Array)
{
if (this._list != null && (this._list.Count - 1) >= index)
{
r = this._list[index];
}
}
else if (index == 0)
{
return this;
}
return r;
}
}

/// <summary>
/// 提供一个字符串索引,简化对Object属性的访问
/// </summary>
/// <param name="PropertyName"></param>
/// <returns></returns>
public JsonProperty this[String PropertyName]
{
get
{
if (this._type == JsonPropertyType.Object)
{
return this._object[PropertyName];
}
else
{
return null;
}
}
set
{
if (this._type == JsonPropertyType.Object)
{
this._object[PropertyName] = value;
}
else
{
throw new NotSupportedException("Json属性不是对象类型!");
}
}
}

/// <summary>
/// JsonObject值
/// </summary>
public JsonObject Object
{
get
{
if (this._type == JsonPropertyType.Object)
return this._object;
return null;
}
}

/// <summary>
/// 字符串值
/// </summary>
public String Value
{
get
{
if (this._type == JsonPropertyType.String)
{
return this._value;
}
else if (this._type == JsonPropertyType.Number)
{
return this._number.ToString();
}
return null;
}
}

public JsonProperty Add(Object value)
{
if (this._type != JsonPropertyType.Null && this._type != JsonPropertyType.Array)
{
throw new NotSupportedException("Json属性不是Array类型,无法添加元素!");
}
if (this._list == null)
{
this._list = new List<JsonProperty>();
}
JsonProperty jp = new JsonProperty(value);
this._list.Add(jp);
this._type = JsonPropertyType.Array;
return jp;
}

/// <summary>
/// Array值,如果属性是非数组的,则封装成只有一个元素的数组
/// </summary>
public List<JsonProperty> Items
{
get
{
if (this._type == JsonPropertyType.Array)
{
return this._list;
}
else
{
List<JsonProperty> list = new List<JsonProperty>();
list.Add(this);
return list;
}
}
}

/// <summary>
/// 数值
/// </summary>
public double Number
{
get
{
if (this._type == JsonPropertyType.Number)
{
return this._number;
}
else
{
return double.NaN;
}
}
}

public void Clear()
{
this._type = JsonPropertyType.Null;
this._value = String.Empty;
this._object = null;
if (this._list != null)
{
this._list.Clear();
this._list = null;
}
}

public Object GetValue()
{
if (this._type == JsonPropertyType.String)
{
return this._value;
}
else if (this._type == JsonPropertyType.Object)
{
return this._object;
}
else if (this._type == JsonPropertyType.Array)
{
return this._list;
}
else if (this._type == JsonPropertyType.Bool)
{
return this._bool;
}
else if (this._type == JsonPropertyType.Number)
{
return this._number;
}
else
{
return null;
}
}

public virtual T GetValue<T>() where T : class
{
return (GetValue() as T);
}

public virtual void SetValue(Object value)
{
if (value is String)
{
this._type = JsonPropertyType.String;
this._value = (String)value;
}
else if (value is List<JsonProperty>)
{
this._list = ((List<JsonProperty>)value);
this._type = JsonPropertyType.Array;
}
else if (value is JsonObject)
{
this._object = (JsonObject)value;
this._type = JsonPropertyType.Object;
}
else if (value is bool)
{
this._bool = (bool)value;
this._type = JsonPropertyType.Bool;
}
else if (value == null)
{
this._type = JsonPropertyType.Null;
}
else
{
double d = 0;
if (double.TryParse(value.ToString(), out d))
{
this._number = d;
this._type = JsonPropertyType.Number;
}
else
{
throw new ArgumentException("错误的参数类型!");
}
}
}

public virtual int Count
{
get
{
int c = 0;
if (this._type == JsonPropertyType.Array)
{
if (this._list != null)
{
c = this._list.Count;
}
}
else
{
c = 1;
}
return c;
}
}

public JsonPropertyType Type
{
get { return this._type; }
}

public override string ToString()
{
return this.ToString("");
}

public virtual string ToString(String format)
{
StringBuilder sb = new StringBuilder();
if (this._type == JsonPropertyType.String)
{
sb.Append("'").Append(this._value).Append("'");
return sb.ToString();
}
else if (this._type == JsonPropertyType.Bool)
{
return this._bool ? "true" : "false";
}
else if (this._type == JsonPropertyType.Number)
{
return this._number.ToString();
}
else if (this._type == JsonPropertyType.Null)
{
return "null";
}
else if (this._type == JsonPropertyType.Object)
{
return this._object.ToString();
}
else
{
if (this._list == null || this._list.Count == 0)
{
sb.Append("[]");
}
else
{
sb.Append("[");
if (this._list.Count > 0)
{
foreach (JsonProperty p in this._list)
{
sb.Append(p.ToString());
sb.Append(", ");
}
sb.Length-=2;
}
sb.Append("]");
}
return sb.ToString();
}
}
}


实例代码

if (Session["access_token"] != null && Session["access_token"] != "")
{
string usernickname = "QQ用户";
string oppid = QQOAuth.GetAccessOpenID(Session["access_token"].ToString().Trim()).Replace("callback( ", "").Replace(" );", "").Trim();
if (!oppid.Contains("error"))
{
JsonObject oppidObj = new JsonObject(oppid);
oppid = oppidObj["openid"].Value;
Session["oppid"] = oppid;
JsonObject newobj = new JsonObject(QQOAuth.GetQQUserInfo(Session["access_token"].ToString(), oppid).Trim());
if (newobj["ret"].Value == "0")
{
usernickname = newobj["nickname"].Value;
Session["usernickname"] = usernickname;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐