Step1帐户登录系统(2.基础代码)


在前面的文章之中,我介绍了一下Step1帐户登录系统的基本编程架构,而在这篇文章,将直接贴出相关的源码,由于这次的开发比较仓促,代码存在很多不完善的地方,因此,适合仅仅用来作为如何实现的代码,而不是适合直接使用,废话少说,直接看代码:

  首先是登录页面的代码,代码分为代码文件和页面文件两个部分:

  Login.aspx代码文件

1  public partial class LoginPage : System.Web.UI.Page
2  {
3    public string url,returnUrl=null;
4    public System.Collections.Specialized.NameValueCollection userInfo=null;
5    protected void Page_Load(object sender, EventArgs e)
6    {
7      url = Request.QueryString["url"];//获得登录完成后回转的URL
8      if (url == null || url.Length <= 0)
9      {
10        if (Request.UrlReferrer != null)
11        {
12          url = Request.UrlReferrer.ToString();
13        }
14      }
15      userInfo=AccountHelper.getUserInfo();//获得当前已经登录的用户信息
16      if (userInfo != null && url != null && url.Length > 1)
17      {
18        returnUrl = AccountHelper.getReturnUrl(url);//如果已经登陆,则直接将回转地址显示在页面的连接上
19      }
20      BaseServer server = AccountHelper.getServerByName(Request["ass"]);//如果通过ass参数指定了登录的类型(用户已经点击图标登录)
21      if (server != null)
22      {
23        if (url != null && url.Length > 0)
24        {
25          AccountHelper.saveUrl(url);//将登录回转的地址记录到Cookie
26        }
27        Response.Redirect(server.getLoginUrl(),true);//转向到相应的登录页面
28      }
29    }
30  }

下面是登录页面的页面文件,实际上就是显示登录界面的HTML内容:

  Login.aspx页面文件

1<%@ Page Language="C#" AutoEventWireup="true" Inherits="Step1.AccountServer.LoginPage"%><html>
2<head>
3<title>Step1.cn账户登录系统</title>
4</head>
5<body>
6<table>
7<tr><td class="icon">
8  <a href='?ass=live.com&url=<%=HttpUtility.UrlEncode(url, System.Text.Encoding.Default)%>'><img src="icons/live.gif"/></a>
9</td><td class="icon">
10  <a href='?ass=google.com&url=<%=HttpUtility.UrlEncode(url, System.Text.Encoding.Default)%>'><img src="icons/google.gif" class="icon"/></a>
11</td><td class="icon">
12  <a href='?ass=yahoo.com&url=<%=HttpUtility.UrlEncode(url, System.Text.Encoding.Default)%>'><img src="icons/yahoo.gif" class="icon"/></a>
13</td><td class="icon">
14  <a href='?ass=xiaonei.com&url=<%=HttpUtility.UrlEncode(url, System.Text.Encoding.Default)%>'><img src="icons/xiaonei.gif" class="icon"/></a>
15</td></tr>
16<tr><td class="desc">
17  <b>Live</b>,<b>MSN</b>,<b>Hotmail</b>用户
18</td><td class="desc">
19  <b>Google</b>,<b>Gmail</b>用户
20</td><td class="desc">
21  <b>Yahoo</b>,<b>Flickr</b>用户
22</td><td class="desc">
23  <b>校内网</b>用户(即将推出)
24</td></tr>
25</table>
26<% if(userInfo!=null){%>
27<div class="user">
28  <b><%=userInfo["name"]%></b> ,您好!您已经使用 <%=userInfo["type"]%> 账号登录
29  <%if(returnUrl!=null) {%><a href="<%=returnUrl %>">点击返回</a><%} %>
30</div>
31<%}%>
32<div class="notice">说明:</div>
33</body>
34</html>

上可以看出,服务端支持哪几种登录方式和登录界面完全没有关系,前台登录界面并不是自动生成的。

  然后是注销的Logout.aspx代码,注销的代码因为没有界面,因此没有页面文件(空文件),仅仅有一个代码文件:

  Logout.aspx代码

1   public partial class LogoutPage : System.Web.UI.Page
2   {
3     protected void Page_Load(object sender, EventArgs e)
4     {
5       //退出系统,如果URL不存在,则返回登录页
6       string url = Request.QueryString["url"];
7       if (url == null || url.Length <= 0)
8       {
9         url = Request.UrlReferrer.ToString();
10       }
11       AccountHelper.clearCookie();//清除用户的Cookie
12       AccountHelper.redirect(url);
13     }
14   }

  注销的代码要简单得多,不过不是最简单的,最简单的是Handler.aspx,这个文件之所以简单是因为同样没有页面文件,再加上其中的代码文件所做的事情都已经调用其它的类来完成,因此只有一个非常简单的代码文件:

  Handler.aspx代码文件

1public partial class HandlePage : System.Web.UI.Page
2{
3  protected void Page_Load(object sender, EventArgs e)
4  {
5    BaseServer server = AccountHelper.getServerByName(Request["ass"]);//根据ASS参数找到对应的服务器类型对象
6    server.parseHandle(this.Context);//由该对象来处理返回请求
7  }
8});

在上面的三个aspx文件的代码之中,无一例外的调用了AccountHelper类,这个类包含一些重要的静态方法,内容如下:

  AccountHelper.cs

 1  public class AccountHelper
 2  {
 3    //清除Cookie
 4    public static void clearCookie()
 5    {
 6      HttpCookie loginCookie = new HttpCookie(Configuration.Instance().cookieName);
 7      loginCookie.Expires = DateTime.Now.AddYears(-10);
 8      loginCookie.Domain = Configuration.Instance().cookieDomain;
 9      loginCookie.HttpOnly = false;
10      HttpContext.Current.Response.Cookies.Add(loginCookie);
11    }
12    //将用户信息加入到Cookie
13    public static void setUserInfo(string account, string name, string type)
14    {
15      HttpCookie loginCookie = new HttpCookie(Configuration.Instance().cookieName);
16      loginCookie.Domain = Configuration.Instance().cookieDomain;
17      loginCookie.Values.Add("account", Convert.ToBase64String(Encoding.UTF8.GetBytes(account)));
18      loginCookie.Values.Add("name", Convert.ToBase64String(Encoding.UTF8.GetBytes(name)));
19      loginCookie.Values.Add("type", Convert.ToBase64String(Encoding.UTF8.GetBytes(type)));
20      loginCookie.Expires = DateTime.Now.AddYears(1);
21      HttpContext.Current.Response.Cookies.Add(loginCookie);
22    }
23    //从Cookie之中获取用户信息
24    public static NameValueCollection getUserInfo()
25    {
26      HttpCookie cookie = HttpContext.Current.Request.Cookies[Configuration.Instance().cookieName];
27      if (cookie != null)
28      {
29        NameValueCollection userInfo = new NameValueCollection();
30        foreach (string key in cookie.Values)
31        {
32          userInfo.Add(key,Encoding.UTF8.GetString(Convert.FromBase64String(cookie.Values[key])));
33        }
34        return userInfo.HasKeys()?userInfo:null;
35      }
36      return null;
37    }
38    //保存URL以便在完成后转向
39    public static void saveUrl(string url)
40    {
41      HttpCookie loginCookie = new HttpCookie(Configuration.Instance().cookieName + "_url");
42      loginCookie.Value = url;
43      loginCookie.Domain=Configuration.Instance().cookieDomain;
44      loginCookie.Expires = DateTime.Now.AddDays(1);
45      HttpContext.Current.Response.Cookies.Add(loginCookie);
46    }
47    //将用户的登录参数加入到URL并回转给Web应用
48    public static void returnOpener()
49    {
50      HttpCookie urlCookie = HttpContext.Current.Request.Cookies[Configuration.Instance().cookieName + "_url"];
51      string url = getReturnUrl(urlCookie == null ? "./" : urlCookie.Value);
52      urlCookie.Expires = DateTime.Now.AddYears(-10);
53      HttpContext.Current.Response.Cookies.Add(urlCookie);
54      redirect(url);
55    }
56    //根据已登陆用户信息和回转的基础URL地址得到回转的URL
57    public static string getReturnUrl(string url)
58    {
59      url += (url.IndexOf("?") > 0) ? "&" : "?";
60      System.Collections.Specialized.NameValueCollection userInfo = HttpContext.Current.Request.Cookies[Configuration.Instance().cookieName].Values;
61      string[] infoArr = new string[userInfo.AllKeys.Length];
62      userInfo.CopyTo(infoArr, 0);
63      url += Configuration.Instance().paramName + "=" + HttpContext.Current.Server.UrlEncode(string.Join(",", userInfo.AllKeys) + ";" + string.Join(",", infoArr));
64      return url;
65    }
66    //转向到指定URL,否则转向到登录页
67    public static void redirect(string url)
68    {
69      if (url == null || url.Length <= 0)
70      {
71        HttpContext.Current.Response.Redirect("Login.aspx");
72      }
73      else
74      {
75        HttpContext.Current.Response.Redirect(url);
76      }
77    }
78    //根据帐户类型的名称返回对应的帐户服务对象
79    public static BaseServer getServerByName(string name)
80    {
81      if (name == null || name.Length < 1) { return null; }
82      BaseServer[] servers=Configuration.Instance().AccountServers;
83      for (int i = 0; i < servers.Length; i++)
84      {
85        if (servers[i].name == name)
86        {
87          return servers[i];
88        }
89      }
90      return null;
91    }
92    public static string getHandleUrl()
93    {
94      return Configuration.Instance().rootUrl + "Handler.aspx";
95    }
96    public static string getLoginUrl()
97    {
98      return Configuration.Instance().rootUrl + "Login.aspx";
99    }
100  }

上面的代码就是比较长的一段了,不过确实是比较重要的一些方法,而下面的BaseServer.cs是一个抽象类,所有的登录类型(例如Google AuthSub类型,Yahoo BBAuth类型)都继承自此类,此类本身不能实例化:

  BaseServer.cs

1  public abstract class BaseServer
2  {
3    public string name;
4    public BaseServer(System.Xml.XmlNode node)
5    {
6      for (int i = 0; i < node.Attributes.Count; i++)
7      {
8        switch (node.Attributes[i].LocalName)
9        {
10          case "name":
11            name = node.Attributes[i].Value;
12            break;
13        }
14      }
15    }
16    public virtual string getLoginUrl()
17    {
18      return "";
19    }
20    public virtual void parseHandle(HttpContext page)
21    {
22    }
23    public virtual string getHandleUrl()
24    {
25      return AccountHelper.getHandleUrl()+"?ass=" + name;
26    }
27  }

  到这里,这些基础的类就都介绍完毕,我之所以不厌其烦的将这些代码都贴上来,主要是为后面介绍每一种登录类型的时候,能够比较清晰的看出是登录过程如何实现的,上面的代码都比较简单,因为都是本站自己的逻辑,但是当涉及到和Google、Yahoo等的帐户服务器交互的时候,很多时候必须完全按照对应的接口来做,因此会比较难懂


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3