zoukankan      html  css  js  c++  java
  • 没完没了的Cookie,读懂asp.net,asp等web编程中的cookies 


     在我刚学会一点asp编程时就知道cookie了,当时照着书上的代码一通输入运行后,一切OK,就这样我自以为掌握了cookie,学javascript照样是一通代码运行成功,cookie到此为止应该是山穷水尽,就那么回事,后来又闻cookie怎么怎么不安全(具体怎么地不清楚)于是逢人说cookie就大呼危险,应该使用session云云.工作半年有余,因为老报错的验证码问题知道session离不开cookie,后来asp.net中的form认证又是cookie一手操办,到最近要在两个站点:一个asp一个asp.net需要实现状态共享,发现还是关于cookie....

      为什么要cookie:
     HTTP协议是一个无状态的协议,作为某个IE浏览器第一次访问某asp或aspx,在原则上说是没有任何区别的,为了标记张三李四等,asp或aspx无一例外想起了cookie,当你访问asp页面时就能有一个ASPSESSIONIDxxx=xxxx这样的cookie被要求写入你的IE,而访问这个站点其他页面时,你所发出的请求无一例外都包括cookies:ASPSesssionIDxxx=xxx,于是在asp里就可以通过Session(username) 获取当前登录的是"张三",当然Session(username) 是保存在服务器内存中的,在asp.net中Session可以保存到SQL服务器或专门的Session服务进程中,但是标识还是通过cookie来维持,而在Asp.net Form认证中更是直接将信息写到cookie中,不过asp.net中你可以选择加密cookie,不过cookie多数情况下只放置一个Username或者userId,需要注意的是加密与否都不能防止重复攻击(通过跨站点脚本获取cookie,再使用这个cookie去访问一些需要相应身份的资源--页面), 当然多数程序员不会傻到把一些敏感信息保存到没加密的cookie里,数据库跟Session会更合适,但是在基于B/S的应用下你很难找到除cookie外的方式来标识某个会话,asp.net可以通过url来标识状态,但是url似乎比cookie更容易暴露, 说到这里情况有点让人沮丧,不过在SSL环境下,多数B/S应用可以达到一个比较高的安全要求的.

     使用cookie做事
    经常的看到很多文章说,用cookie保存用户喜欢的颜色啊,搞个投票程序记录状态什么地,这其实搞歪了,cookie最好还是用来标记会话状态比较好,这样一来你就可以在不同的程序中保持会话状态(asp与asp.net),以及同一域名不同主机下保持状态(a1.domain.com跟a2.domain.com等),这些在需要扩充站点功能时能派上用场.

     同样的Cookie
     无论Asp或Asp.net 他们使用的cookie其实完全一样,由于语言与沟通问题曾经导致我草率的认为他们是不同的两个cookie.
    一个完整的cookie 应该是 有个名字,接着有个叫Domain的属性,还要带个Path, 凡是这个三个属性相同的Cookie是同个cookie, 在 一般在asp程序里你会使用 Request.Cookies("xxx")="value",来设置一个cookie,但是这个cookie,在你使用http://www.xxx.com/,时跟http://xxx.com/访问时其输出的domain是不同的,因此,你在http://www.xxx.com/登录后,在ie中输入http://xxx.com/的页面时发现你已经不是登陆状态,原因就在于你没设置domain属性,IE在使用Get或Post请求数据时会附加跟域名domain相匹配的cookie.
     因此你想在A.wow52.cn登录后,在B.wow52.cn同样处于登陆状态,也就是在访问B.wow52.cn上的页面时可以读到A.wow52.cn设置的cookie(username)你需要写入如下一段cookie (asp版)
    response.Cookies("wow52UserCookie")="张三"
    response.Cookies("wow52UserCookie").domain=".wow52.cn"
    response.Cookies("wow52UserCookie").Expires="2009-12-1"

    '//不设置Expires 属性 cookie默认在浏览器关闭后失效(内存cookie)
    response.Cookies("wow52UserCookie").Path="/"

    这样一翻设置后,你在B.wow52.cn中就可以读到这个"张三",  Name,Domain, Path 三个属性来标识一个唯一的cookie, 而其中的Domain属性决定浏览器是否附加cookie信息给新请求的页面,不过你不要指望在http://www.wow52.cn/ 输出一个domain是.gyzs.net的cookie,让浏览器在请求http://www.gyzs.net/的页面时带上这个cookie, IE在出于安全的原因会明确拒绝这样的做法,想使用这样方式来实现多域名单点登录是行不通的.

    清除一个cookie:

     在用户退出时(注销)需要清除cookie,不过遗憾的是response.Cookies并没提供删除cookie的办法,唯一的做法是设置某个cookie过期,也就是设置Expires属性,代码看起来应该如下
     response.Cookies("wow52UserCookie")="" '//设置成空字符
    response.Cookies("wow52UserCookie").domain=".wow52.cn"
    response.Cookies("wow52UserCookie").Expires="1990-1-1"  '//1990年,现在是2009年不要发生时光倒转就好

    response.Cookies("wow52UserCookie").Path="/"
    Response.Redirect('/index.html')

    这段代码会输出一个Set-cookie:..... 发送给浏览器(你需要一些代理软件来观察这些),浏览器在收到信息后就将这个cookie抛弃掉,同时Redirect迫使浏览器马上访问一个新页面,这个时候浏览器就不会发送名为wow52UserCookie的这个cookie了他过期了,只要IE不发送,那么对服务器的asp来说它就消失了,被删除了,我现在不知道你是"张三"还是"李四"了, 最后你如果看asp.net里的反编译代码,FormsAuthentication.SignOut()这句代码做的事情几乎一样(当然设置不同名称,domain,跟path,这个你可以在web.config里配置).

     asp跟asp.net互通cookie:

      几年前我也做过同样的测试,asp页中写个cookie,asp.net读出这个cookie, 由于一些社会自然原因,当时我用的是"安定法安定发"类似的中文数据,结果在asp.net中没读出来,或许是读出一堆乱码,于是我下了结论,asp,asp.net不能恭享cookie,这个想法直到2年后才发现自己的无知,在GB2312的asp页面下(asp pagecode="936"),你输出的cookie,asp会进行UrlEncode--采用GB2312编码, 这个在多数只使用asp的情况下没什么,asp会自动解编码,但是asp.net就不一样了,你必须使用Server.UrlDecode()才可以获取正常的内容,不过这个时候你的web.config设置是gb2312的,如果没设置或设置为utf-8,那么你就需要使用HttpUtility.UrlDecode(value,Encoding.GetEncoding("GB2312"))来解码了,另外建议只使用英文字母跟数字来设置cookie.Name属性,以免名称上也出现分歧. 反过来在asp.net写cookie,asp中读取,你需要做的是把cookie.value用UrlEncode编码下即可,同样注意下编码要互相对应.

  • 相关阅读:
    219. Contains Duplicate II
    189. Rotate Array
    169. Majority Element
    122. Best Time to Buy and Sell Stock II
    121. Best Time to Buy and Sell Stock
    119. Pascal's Triangle II
    118. Pascal's Triangle
    88. Merge Sorted Array
    53. Maximum Subarray
    CodeForces 359D Pair of Numbers (暴力)
  • 原文地址:https://www.cnblogs.com/wdfrog/p/1427937.html
Copyright © 2011-2022 走看看