相关文章:
Cookie应用完全解析(一):asp.net中Cookie技术
Cookie应用完全解析(三): cookie 加密配置 使用SSL加密协议建立WWW站点的全过程
Cookie应用完全解析(三): cookie 加密配置 使用SSL加密协议建立WWW站点的全过程
推荐:
Cookies揭秘 [Asp.Net, Javascript]
问题:
javascript脚本无法获取服务端写入的Cookies
Cookie 是什么?
在asp.net中,如何使用?
1 Cookie 是什么?
Cookie:电脑中记录用户在网络中的行为的文件;网站可通过Cookie来识别用户是否曾经访问过该网站。(摘自 http://gb.cri.cn/17004/2007/03/08/121@1487554.htm)
2在asp.net中,如何使用?
ASP.NET通过System.Web空间名称也提供了cookie的访问。虽然你不应该使用cookie来存储一些敏感性的数据,但是,它们是处理锁细数据的一个极好的选择,比如颜色参数选择或者最后一次访问日期。
传递cookies
cookie是存储在客户端计算机的一个小文件。如果你是一个Windows用户,可以在用户路径中查看Cookies路径,即为Documents And Settings路径。这一路径包含这一文件名称的文本文件:
username @ Web site domain that created the cookie
(用户名称@建立cookie的站点域名)
.NET System.Web空间名称包含三个类,你可以使用它们来处理客户端的Cookies:
HttpCookie:提供一个建立和操作独立HTTP cookies的安全类型的方式。
HttpResponse:Cookies属性允许操作客户端cookies。
HttpRequest:Cookies属性允许访问客户端操作的cookies。
HttpResponse和HttpRequest对象的Cookies属性将返回一个HttpCookieCollection对象,它包含着,将单独的cookies添加到集合(collection)中,以及从集合(collection)获得一个单独的cookies。
HttpCookie类
HttpCookie类针对于客户存储之用而建立的单独cookies。一旦HttpCookie对象被建立,你可以将其添加到HttpResponse对象的Cookies属性中。同样的,你可以通过HttpRequest对象访问现有的cookies。HttpCookie类包含以下的公有属性:
Domain(域名):获得或设置与cookie有关的域名,可用于限制特定区域的cookie访问。
Expires(期限):获得或设置cookie的终止日期和时间,你可以将其设置为一个过去的日期以自动终止或者删除cookie。
Names(名称):获得或设置cookie名称。
Path(路径):获得或设置cookie的虚拟路径。这一属性允许你限制cookie范围,也就是说,访问cookie只能限制于一个特定的文件夹或者路径。设置这一属性限制为只能访问特定路径和该路径下的所有文件。
Secure(安全):发信号以表示是否使用Secure Sockets Layer (SSL)来发送cookie值。
Value(值):获得或设置一个单独的cookie值。
Values(信息):返回包含在cookie中的key/value的一个集合。
使用样例:
/// <summary>
///写入Cookie,并返回cookie
/// </summary>
/// <param name="userData">Base64后的实体数据</param>
/// <returns>加密的cookie</returns>
protected virtual HttpCookie GetAuthCookie(string userData, string userName)
{
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
3,
userName,
System.DateTime.Now,
DateTime.Now.AddMinutes(expiresMinutes),
false,
userData,
FormsAuthentication.FormsCookiePath);
string encTicket = FormsAuthentication.Encrypt(ticket);
if ((encTicket == null) || (encTicket.Length < 1))
{
throw new HttpException("Unable_to_encrypt_cookie_ticket");
}
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
cookie.Path = "/";
cookie.Secure = FormsAuthentication.RequireSSL;
cookie.HttpOnly = true;
if (this.domain != string.Empty)
{
bool urlIsDomain = HttpContext.Current.Request.Url.Host.ToString().EndsWith(this.domain);
if (urlIsDomain)
{
cookie.Domain = this.domain;
}
}
if (ticket.IsPersistent)
{
cookie.Expires = ticket.Expiration;
}
HttpContext.Current.Response.Cookies.Add(cookie);
return cookie;
}
同样,Response对象包含一个SetCookie方法,这一方法可以接受一个HttpCookie对象。
我的cookie在哪里?
一旦cookies被保存在客户端,有多种不同的方法以提供你访问它们。如果你知道cookie名称,可以使用HttpResponse对象很容易地访问它的值。
一个实际实际案例:
前段时间做考试系统中在线考试部分的功能,需要将考生在线时对试题的作答情况记录下来,参考了一下别人的做法,解决这个问题的思路有两个:一是在数据库中建表,用来保存考生作答时的答案,等考生交卷后再将临时保存考生答题信息的表的数据插入到记录考生答题情况的正式表中;二是不在数据库中用表保存考生交卷前对试题的作答情况,而是将考生交卷前的答题信息保存在文件中,等考生交卷后将记录考生答题情况文件中的信息写入数据库。第一种思路的优点是考生答题过程中的答题情况可以确保更好的正确性,缺点是不能排除与数据库连接发生错误从而导致不能将数据写入的可能,此外,另一个缺点是在线考试时考生较多,如果每答一题就对数据库操作一次,这样频繁地对数据库的访问和操作会增大数据库的压力,有可能导致严重的后果。第二种思路的优点恰恰就是能够避免出现第一种思路的缺点,缺点就是因为考试时答题情况的数据非常重要,记录在文件中则有被窜改的可能。综合考虑客户实施部署考试系统的环境和实际情况之后,决定采用第二种思路。针对第二种思路的缺点,鉴于其网络环境为内部局域网,考生使用的机器配备的输入输出设备有限等情况,其缺点还不足以有多大的概率发发生。而且,客户一再要求在线考试时候,要将一切影响考试正常进行的因素降到最低,尽量减少对数据库的访问,权衡之后决定采用第二种思路。从第二种思路出发,我采用cookie文件来临时保存考生的答题信息这一做法。由于之前没有尝试过这种做法,所以先到网上找了一大通资料,先了解了解。从最初的了解到组后将功能实现,花了大概两三天时间。走了不少弯路,故将其过程记录下,以免日后遇到同样的问题重蹈覆辙。
实现思路:
采用该方法,直至最后交卷,将cookie文件中保存的考生答题信息写入数据库,其优化和合理的流程是:考生登录->创建cookie文件->考生答题->更新cookie文件->继续答题->更新cookie文件->交卷->获取cookie文件答题信息->写入数据库(同时将获取的数据以xml格式文件上传到服务器以备后用)。在这个过程中,对于cookie文件的操作是重点,因为它记录的信息至关重要,更新cookie文件时必须考虑到考生作答的试题是之前就已经在cookie文件里有记录还是第一次对该题作答,如果是第一次作答,则在原cookie文件中加上作答信息即可;如果之前就已经作答过,现在来修改,则必须在cookie文件中找出保存在cookie文件中对应试题的信息进行更新,因为考生每作答一次就必须对cookie文件进行更新,所以特将对cookie文件的更新写成一个方法,这样可以重复调用。
所有的思路和步骤都已经清晰,代码则就是水到渠成的事了,下面是更新cookie的最重要部分代码:
/// <summary>
/// 更新cookie文件内容
/// </summary>
private void UpdateCookie()
{
// 往cookie集合中增加答题信息
int c_timulx = Convert.ToInt32(ViewState["c_timulx"]);// 题目类型
string c_bianhao = Convert.ToString(ViewState["c_bianhao"]);// 试题编号
string cookieID = ViewState["cookieID"].ToString();
string daan = this.GetDaan(c_timulx);// 获取考生答案
// 获取原cookie文件中的内容
string oldCookieValue = "";
if (Request.Cookies[cookieID].Value != null)
{
oldCookieValue = Request.Cookies[cookieID].Value;
}
// 如果原cookie文件中已经存在当前题的答题信息,则取出原cookie文件中的当前题的信息,进行修改
string newCookieValue = "";// 新cookie文件的内容
string newAnswer = "|" + c_timulx.ToString() + "," + c_bianhao;// 当前题在原cookie文件中的内容
if (oldCookieValue.Contains(newAnswer))
{
// 删除原cookie文件
HttpCookie oldCookie = Request.Cookies[cookieID];
oldCookie.Expires = DateTime.Now.AddHours(-1);
Response.Cookies.Add(oldCookie);
// 组装新cookie文件的内容
string[] temp = oldCookieValue.Split(''|'');
foreach (string s in temp)
{
string[] tempDaan = s.Split('','');
string element1 = tempDaan[0];//
string element2 = tempDaan[1];
string element3 = tempDaan[2];
if (c_timulx.ToString() == element1 && c_bianhao == element2)// 如果是编辑曾在cookie中有答案保存的题目
{
newCookieValue = oldCookieValue.Replace("|" + element1 + "," + element2 + "," + element3, "|" + c_timulx.ToString() + "," + c_bianhao + "," + daan);
}
}
}
else// 如果原cookie文件中不存在当前题的答题信息,则往原cookie文件中添加当前题的答案
{
// 删除原cookie文件
HttpCookie oldCookie = Request.Cookies[cookieID];
oldCookie.Expires = DateTime.Now.AddHours(-1);
Response.Cookies.Add(oldCookie);
// 组装新cookie文件的内容
newCookieValue = oldCookieValue + "|" + c_timulx.ToString() + "," + c_bianhao + "," + daan;
}
// 组成新的cookie文件内容,创建cookie对象
HttpCookie objcookie = new HttpCookie(cookieID, newCookieValue);
// 设置cookie文件的生命周期
DateTime now = DateTime.Now;
TimeSpan ts = new TimeSpan(2, 0, 0);// 生命周期设为2个小时
objcookie.Expires = now + ts;
// 设置cookie采用SSL传送方式
//objcookie.Secure = true;
Response.Cookies.Add(objcookie);
}
技术运用告一段落:
安全怎么来保证呢?
传输前加密Cookie,防止数据被人偷看(如果没有敏感数据,倒没什么);传输的中,是否完整性呢?常规的是,配置SSL 加密方式。
下面将有三个问题:SSL 是什么?怎么配置?怎么使用?