当重复的代码或相似的事件>=2个时,我都会想一下,是否还可能有第3个,第4个相近的,如果有,就会统一处理,组件就是设计的再通用一些。
2.1:让用户以最简单的方式使用或调用组件,编写代码量最小化;
3:本人组件设计的简单思路过程:(5行代码的设计思路)
在html里直接写死?感觉不给力,而且如果扩展多几个第三方登陆时,又要去组合网址,是件麻烦事。
所以我想到了应该有UI类,应该有个GetHtml(),这样来解决让调用更简单。
实现UI.GetHtml()方法: 这里也是有点知识点的,为了让代码简洁化,我花了不少时间思考,通过良好的代码组合设计,减少代码量的编写。
public static string GetHtml()
{
string link =
" <a href=\"{0}\" target=\"_blank\"><img src=\"{1}\" /></a> ";
StringBuilder sb =
new StringBuilder();
foreach (KeyValuePair<
string,OAuth2Base> ob
in OAuth2Factory.ServerList)
{
if (!
string.IsNullOrEmpty(ob.Value.AppKey))
{
sb.AppendFormat(link,
string.Format(ob.Value.OAuthUrl, ob.Value.AppKey,System.Web.HttpUtility.UrlEncode(ob.Value.CallbackUrl), ob.Key), ob.Value.ImgUrl);
}
}
return sb.ToString();
1:应该有一个方法,可以获取当前所有的授权类型:
OAuth2Factory.ServerList。
2:授权类型应该包括一些配置项,可以直接读取:
ob.Value.OAuthUrl, ob.Value.AppKey,ob.Value.ImgUrl
在想出这种方法时,还没开始设计OAuth2授权相关类,所以当时还只是伪代码,随着OAuth2类被完善,这里的代码就简单成型了。
3.2:OAuth授权类设计(传说的抽象+工厂): 1:应该有个基类:OAuth2Base(包括通用的方法和属性)
2:继续基类 OAuth2Base,实现不同的授权:SinaWeiboOAuth、QQAuth、其它...等!
3:有个工厂OAuth2Factory来返回当前的授权类型(正如数据库组件来设计当前是操作哪种数据库类型)
在OAuth2Factory里,我们通过预先注册所有的子类授权,来汇总所有的授权类型。
所以GetHtml里可以获取所有授权类型进行遍历组装。
static Dictionary<
string, OAuth2Base> _ServerList;
/// <summary> /// 获取所有的类型(新开发的OAuth2需要到这里注册添加一下) /// </summary> internal static Dictionary<
string, OAuth2Base> ServerList
{
get {
if (_ServerList ==
null)
{
_ServerList =
new Dictionary<
string, OAuth2Base>(StringComparer.OrdinalIgnoreCase);
_ServerList.Add(OAuthServer.SinaWeiBo.ToString(),
new SinaWeiBoOAuth());
// 新浪微博 _ServerList.Add(OAuthServer.QQ.ToString(),
new QQOAuth());
// QQ微博 }
return _ServerList;
}
整体的设计并不复杂,只要实现后,就可以实现授权,并得到第三方的token和openid数据。
3.3 OAuth2 绑定 网站的账号实现第三方登陆: 在原来网站的数据库里,添加字段?或者创建新表,再进行设计?
考虑到这样的设计,和网站代码结合度必然很深,不可能做到通用型,而且不同网站,用的是不同的数据库,那得编写多少种不同的脚本?
所以思前想后,将数据外置存储在外部文本,考虑到CYQ.Data V5已经接近完美的支持文本数据库及CodeFirst操作,所以引用它做为默认的外置数据库操作类。
当然拿到源码后,如果对于外存储过块需要调整或使用其它框架,这个自行操作了,不干涉内政。
如果对比上面的源码截图,你应该发现,所以类都提到了,只剩下最后一个:OAuth2Account ,它就是实现和网站绑定的罪人。
代码也很简单的说(除了继承自OrmBase和构造函数指定了表名和文本存储路径,基本上就是一个常见的实体类了):
public class OAuth2Account:CYQ.Data.Orm.OrmBase
{
public OAuth2Account()
{
base.SetInit(
this,
" OAuth2Account ",
" Txt Path={0}App_Data ");
}
private int _ID;
public int ID
{
get {
return _ID;
}
set {
_ID = value;
}
}
private string _OAuthServer;
/// <summary> /// 授权的服务类型 /// </summary> public string OAuthServer
{
get {
return _OAuthServer;
}
set {
_OAuthServer = value;
}
}
private string _Token;
/// <summary> /// 保存的Token /// </summary> public string Token
{
get {
return _Token;
}
set {
_Token = value;
}
}
private string _OpenID;
/// <summary> /// 保存对应的ID /// </summary> public string OpenID
{
get {
return _OpenID;
}
set {
_OpenID = value;
}
}
private string _BindAccount;
private DateTime _ExpireTime;
/// <summary> /// 过期时间 /// </summary> public DateTime ExpireTime
{
get {
return _ExpireTime;
}
set {
_ExpireTime = value;
}
}
private string _NickName;
/// <summary> /// 返回的第三方昵称 /// </summary> public string NickName
{
get {
return _NickName;
}
set {
_NickName = value;
}
}
private string _HeadUrl;
/// <summary> /// 返回的第三方账号对应的头像地址。 /// </summary> public string HeadUrl
{
get {
return _HeadUrl;
}
set {
_HeadUrl = value;
}
}
/// <summary> /// 绑定的账号 /// </summary> public string BindAccount
{
get {
return _BindAccount;
}
set {
_BindAccount = value;
}
}
在OAuth2Base基类里有两个和内置文本数据库打交首的函数:GetBindAccount和SetBindAccount:
/// 添加绑定账号 /// </summary> /// <param name="bindAccount"></param> /// <returns></returns> public bool SetBindAccount(
string bindAccount)
{
bool result =
false;
if (!
string.IsNullOrEmpty(openID) && !
string.IsNullOrEmpty(token) && !
string.IsNullOrEmpty(bindAccount))
{
using (OAuth2Account oa =
new OAuth2Account())
{
if (!oa.Exists(
string.Format(
" OAuthServer='{0}' and OpenID='{1}' ", server, openID)))
{
oa.OAuthServer = server.ToString();
oa.Token = token;
oa.OpenID = openID;
oa.ExpireTime = expiresTime;
oa.BindAccount = bindAccount;
oa.NickName = nickName;
oa.HeadUrl = headUrl;
result = oa.Insert(CYQ.Data.InsertOp.None);
}
}
}
return result;
}
由于是CodeFirst及设计的是文本数据库,所以不用去兼容不同网站的数据库,自动生成文本数据库外置,只需要好好玩这个实体就可以了。
简单的就介绍到这了,设计并不复杂,代码量并不多,方法和成员也很少。 源码点击下载: (
![download](http://www.cyqdata.com/Editor/Upload.ashx?fid=675)
)
看完本文,下完源码,也许您可能会有以下功能需要进行调整,这里给出指导与说明:
2:增加授权种类:继承OAuth2Base,参考已有的新浪微博和QQ进行操作,当然也可以联系我让我添加。
3:如何取得绑定后的表数据:只要调用new
OAuth2Account().Select().Bind(列表); a:保留CYQ.Data V5版本,更换数据库,只需要修改
OAuth2Account 类的构造函数的数据库链接更换为您现在使用的数据库链接即可。 CYQ.Data V5版本目前仅支持以下数据库(mssql、mysql、oracle、aceess、sqlite、txt、xml),前三种需要授权使用,后四种免费使用。
b:移除CYQ.Data V5版本,更换底层组件,您只要重写OAuth2Base中的
SetBindAccount和GetBindAccount两个方法即可,然后自己另外存储数据介质。
不管是哪种,对于有点开发经验的新老手来说,都是相对比较简单。
本文转自cyq1162 51CTO博客,原文链接:http://blog.51cto.com/cyq1162/1052583 ,如需转载请自行联系原作者