• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Asp.Net使用加密cookie代替session验证用户登录状态 源码分享

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

首先 session 和 cache 拥有各自的优势而存在.  他们的优劣就不在这里讨论了.

本实例仅存储用户id于用户名,对于多级权限的架构,可以自行修改增加权限字段

 

本实例采用vs2010编写,vb和c#的代码都是经过测试的;一些童鞋说代码有问题的 注意下   

什么? 你还在用vs2008 vs2005? 请自行重载 带有 optional 标致的函数

 

童鞋们提到的 密码修改后 要失效的问题 当时没有想到 个人认为 大致方向可以》

》1. 每个用户生成1个xml 里面保存随机的几个字符 或者修改密码的时间戳也行 

》2. 这个文件在用户刚注册 或修改密码时候生成写入; 写入的同时需要更新当前用户的cookie 否则当前用户也会失效

》3. 在本实例的基础上 加1个字段 内容为 1中的若干字符 本实例在cookie写入15分钟后才会重新写入新的cookie;可以在重新写入cookie前 比对这几个若干字符是否匹配 用 StreamReader 即可

》4. 以上不知 大家看懂了没有呢


以下类实现了 使用加密cookie代替session验证用户登录状态 支持 1小时/1周 有效期2种模式 (期间有新的请求则更新失效时间)

项目源码下载地址 http://www.370b.com/bbsx/cookie-login/cookie.rar

csdn下载地址 http://download.csdn.net/detail/rayyu1989/4265766


在自定义字符 CustomCode 不被知道的情况下 该加密过程是相对安全的.
你还可以更改其中 的 2处MD5哈希值 生成的方式、DEChar(ENChar)混淆字符 让代码更与众不同


欢迎大家拍砖

加密后的cookie值枚举:

n=rayyu_EJPSiju2JJNeh5&u=VWpc9dv5v8e4APbbhJmSP+yifwZNEcyRy6V/RwzqV2pmo+x6hNLHI/pLlzl8+KgdWpMHtTTOYpGMe3tCrAIKkmeCrKG7BpSVUYF0piopz757NPb43Z4ehA==&i=56-76-68-35-4A-37-57-35

n=rayyu_P5O7ouiq5JVaMf&u=gWz/itCIlbupWCv7iziBuYCwT1SF4+IbyFbwa5Hmm+up4iuCxKMCl24+bLRb0Y/6RMyfzcpuJwu8gT/Yqg1UV1bd9UqgQYzrLdibP9zaXkYjYyT56gkCBg==&i=5B-65-54-34-6G-35-4C-45

n=rayyu_bNJuGxps3Kqtxl&u=kUorl6z713eYdjkhRidocZKHMh2Mw6j5LowmevsWiKZsn81dzlsPcH4fp1VJsi2dtObeYvMJTCybLrv45TsdLIT7nhZcQJdxKGn1oaK/7a3Ldfte6zoQqg==&i=4H-5B-53-6A-6H-75-32-4H

n=rayyu_TF0hpOgdGhliK8&u=1O9Zi4V9Qj2HH63dEfXaLaoj3X6ea9azIBjuLjFBJqhiTQefz2x161IIDpWaviJr1TTECBdb4NCIiFOEsEY9C4gl+/Equjc7tGpO12ixEkZz70bMg48M9w==&i=4H-4E-65-68-35-7A-5B-35

 

n=rayyu_9INryZvNo1pCKm&u=wQgRgtf+uy9jKQXJhr7DerZtFeYmm2Lx10Asgf52HTzkar9iHXkVaJJqHtwWA9K635QU4bGLYZPWl3nj0rxOhOe93ew+bIAR8FWr2zPwvfZ++TwB3670LQ==&i=4F-37-6F-75-6A-71-35-4H

 

 

客户端可以获取cookie的 n值 来简单判断是否登录 n为用户名,配合静态页和缓存 动态显示登录状态

VB.NET调用: (Rayyu 是 namespace)

[vb] view plaincopy
 
  1. Dim user As New Rayyu.User() '初始化用户信息(检测当前请求用户是否登录)  
  2. If user.Online Then  
  3. Response.Write("<br />name:" & user.Name & ",online:" & user.Online & ",id:" & user.ID)  
  4. End If  
  5.   
  6.   
  7. Dim user2 As New Rayyu.User(1, "用户名"False'初始化(写入新用户)  

 

 

C#调用:(Rayyu 是 namespace)

 

[csharp] view plaincopy
 
  1. Rayyu.User user = new Rayyu.User();// 初始化用户信息(检测当前请求用户是否登录)  
  2.             Rayyu.User user2 = new Rayyu.User(1, "用户名"false);// 初始化(写入新用户) false 表示1小时  true表示1周  
  3.   
  4.   
  5.             if (user.Online)  
  6.             {  
  7.                 Response.Write("<br />name:" + user.Name + ",online:" + user.Online + ",id:" + user.Id);  
  8.             }  



 

VB.NET 源代码:

 

[vb] view plaincopy
 
  1. Imports System.Web  
  2. Imports System.Text.RegularExpressions  
  3. Imports System.Text  
  4. Imports System.Security.Cryptography  
  5.     ''' <summary>  
  6.     ''' 用户登录机制 支持1小时/1周状态  
  7.     ''' </summary>  
  8.     ''' <remarks></remarks>  
  9.     Public Class User  
  10. #Region "自定义参数"  
  11.         ''' <summary>  
  12.         ''' 自定义字符 用于第一层加解密密匙  
  13.         ''' </summary>  
  14.         ''' <remarks></remarks>  
  15.     Private Const CustomCode As String = "QQ:867863456"  
  16.     ''' <summary>  
  17.     ''' cookie名  
  18.         ''' </summary>  
  19.         ''' <remarks></remarks>  
  20.         Private Const CookieName As String = "userinfo"  
  21.         ''' <summary>  
  22.         ''' Cookie作用域  
  23.         ''' </summary>  
  24.         ''' <remarks></remarks>  
  25.     Private Const CookieDomain As String = ".370b.com"  
  26.         ''' <summary>  
  27.         ''' 编码  
  28.         ''' </summary>  
  29.         ''' <remarks></remarks>  
  30.         Private Shared Encoder As Encoding = Encoding.UTF8  
  31.         ''' <summary>  
  32.         ''' 用户名的正则检测 我的是:首位由字母或者汉字构成,由字母、数字、下划线、和汉字的 2-20位的字符 组合而成 的  
  33.         ''' </summary>  
  34.         ''' <remarks></remarks>  
  35.         Private Const RegexUserName As String = "[a-zA-Z\u4e00-\u9fa5][\w\u4e00-\u9fa5]{1,19}"  
  36.         ''' <summary>  
  37.         ''' 区域化信息设置  
  38.         ''' </summary>  
  39.         ''' <remarks></remarks>  
  40.     Private Shared ReadOnly Format As Globalization.CultureInfo = New System.Globalization.CultureInfo("zh-CN"True)  
  41. #End Region  
  42. #Region "回调参数"  
  43.         ''' <summary>  
  44.         ''' 是否在线  
  45.         ''' </summary>  
  46.         ''' <remarks></remarks>  
  47.         Public ReadOnly Property Online As Boolean  
  48.             Get  
  49.                 Return _Online  
  50.             End Get  
  51.         End Property  
  52.         Private _Online As Boolean = False  
  53.         ''' <summary>  
  54.         ''' 用户ID (Online=true情况下使用)  
  55.         ''' </summary>  
  56.         ''' <remarks></remarks>  
  57.         Public ReadOnly Property Id As Integer  
  58.             Get  
  59.                 Return _Id  
  60.             End Get  
  61.         End Property  
  62.         Private _Id As Integer  
  63.         ''' <summary>  
  64.         ''' 用户名 (Online=true情况下使用)  
  65.         ''' </summary>  
  66.         ''' <remarks></remarks>  
  67.         Public ReadOnly Property Name As String  
  68.             Get  
  69.                 Return _Name  
  70.             End Get  
  71.         End Property  
  72.         Private _Name As String  
  73.         ''' <summary>  
  74.         ''' 有效期是否为7天  
  75.         ''' </summary>  
  76.         ''' <remarks></remarks>  
  77.         Public ReadOnly Property IsWeek As Boolean  
  78.             Get  
  79.                 Return _IsWeek  
  80.             End Get  
  81.         End Property  
  82.         Private ReadOnly _IsWeek As Boolean  
  83. #End Region  
  84.         ''' <summary>  
  85.         ''' 初始化用户信息(检测当前请求用户是否登录)  
  86.         ''' </summary>  
  87.         ''' <remarks></remarks>  
  88.         Public Sub New()  
  89.             '读取cookie  
  90.             Dim cookie As HttpCookie = HttpContext.Current.Request.Cookies(CookieName)  
  91.             If cookie IsNot Nothing Then  
  92.                 '存在cookie  
  93.                 Dim value As String = cookie.Values("u"), key As String = cookie.Values("i"), tname As String = cookie.Values("n")  
  94.                 cookie = Nothing  
  95.             If tname IsNot Nothing AndAlso value IsNot Nothing AndAlso key IsNot Nothing AndAlso Regex.IsMatch(key, "^[1-8A-H]{2}(-[1-8A-H]{2}){7}$", Text.RegularExpressions.RegexOptions.None) Then  
  96.                 '存在对应键值  
  97.                 Dim keybyte As Byte() = toByte(DEChar(key)) '解密密匙的后8位字节 由参数i构成  
  98.                 If keybyte IsNot Nothing Then  
  99.                     Dim autocode() As Byte '解密密匙的前16位字节 由用户UserAgent,用户名,自定义字符 组合而成 的 md5   
  100.                     Using m As New System.Security.Cryptography.MD5CryptoServiceProvider()  
  101.                         autocode = m.ComputeHash(Encoder.GetBytes(String.Format(Format, "{0}_{2}_{1}", HttpContext.Current.Request.UserAgent, tname, CustomCode)))  
  102.                         m.Clear()  
  103.                     End Using  
  104.                     Dim keyboard() As Byte = New Byte(keybyte.Length + autocode.Length - 1) {}  
  105.                     autocode.CopyTo(keyboard, 0)  
  106.                     keybyte.CopyTo(keyboard, autocode.Length)  
  107.                     value = DesDecrypt(value, keyboard)  
  108.                     If value.Length > 0 Then  
  109.                         '解密成功 第一层合法  
  110.                         Dim values As Match = Regex.Match(value, "^(?<md5>[\w]{32})(?<isweek>[01])(?<id>[\d]{1,10})(?<name>" & RegexUserName & ")\|(?<exp>[\d]{1,19})$")  
  111.                         If values.Success Then  
  112.                             Dim LostDateTime As Long  
  113.                             If Integer.TryParse(values.Groups("id").Value, Me._Id) AndAlso Me._Id > 0 AndAlso Long.TryParse(values.Groups("exp").Value, LostDateTime) AndAlso LostDateTime > 0 Then  
  114.                                 '解密后的字符串格式正确  
  115.                                 Me._IsWeek = (values.Groups("isweek").Value = "1")  
  116.                                 '此md5用于验证解密后的字符串 由用户id,用户名,cookie写入时间,自定义字符串 以及有效期是否是1周 组合  
  117.                                 Dim md5 As String = MD5Public(String.Format(Format, "{0}{5}{1}{2}:rayyu.{3};{4}", values.Groups("id").Value, values.Groups("exp").Value, values.Groups("name").Value, CookieDomain, IsWeek, CustomCode))  
  118.                                 If md5 = values.Groups("md5").Value Then  
  119.                                     'md5正常  
  120.                                     Dim lostdate As Double = (Now - New DateTime(LostDateTime)).TotalMinutes  
  121.                                     Dim l_a As Integer  
  122.                                     If IsWeek Then  
  123.                                         l_a = 10080  
  124.                                     Else  
  125.                                         l_a = 60  
  126.                                     End If  
  127.                                     If lostdate > 0 AndAlso lostdate < l_a Then  
  128.                                         'cookie在有效期内  
  129.                                         Me._Name = values.Groups("name").Value  
  130.                                         Me._Online = True  
  131.                                         If lostdate > 15 Then  
  132.                                             'cookie以写入超过15分钟,从新写入1次cookie  
  133.                                             SetUser(Me._Id, Me._Name, Me._IsWeek, autocode)  
  134.                                         End If  
  135.                                     End If  
  136.                                 Else  
  137.                                     Me._Id = 0  
  138.                                     Me._Name = Nothing  
  139.                                 End If  
  140.                             End If  
  141.                         End If  
  142.                     End If  
  143.                 End If  
  144.             End If  
  145.             End If  
  146.         End Sub  
  147.         ''' <summary>  
  148.         ''' 初始化(写入新用户)  
  149.         ''' </summary>  
  150.         ''' <param name="userid">用户id</param>  
  151.         ''' <param name="username">用户名</param>  
  152.         ''' <param name="isweek">是否保持一周登录状态</param>  
  153.         ''' <remarks></remarks>  
  154.         Public Sub New(ByVal userId As IntegerByVal userName As StringByVal isWeek As Boolean)  
  155.             SetUser(userId, userName, isWeek)  
  156.             Me._ID = userId  
  157.             Me._Name = userName  
  158.             Me._IsWeek = isWeek  
  159.             Me._Online = True  
  160.         End Sub  
  161.         ''' <summary>  
  162.         ''' 写入用户  
  163.         ''' </summary>  
  164.         ''' <param name="userid">用户id</param>  
  165.         ''' <param name="username">用户名</param>  
  166.         ''' <param name="isweek">是否保持一周登录状态</param>  
  167.         ''' <param name="autocode"></param>  
  168.         ''' <remarks></remarks>  
  169.         Private Shared Sub SetUser(ByVal userid As IntegerByVal username As StringByVal isweek As BooleanOptional ByVal autocode As Byte() = Nothing)  
  170.             If autocode Is Nothing Then  
  171.                 '解密密匙的前16位字节 由用户UserAgent,用户名,自定义字符 组合而成 的 md5   
  172.                 Using m As New System.Security.Cryptography.MD5CryptoServiceProvider()  
  173.                     autocode = m.ComputeHash(Encoder.GetBytes(String.Format(Format, "{0}_{2}_{1}", HttpContext.Current.Request.UserAgent, username, CustomCode)))  
  174.             End Using  
  175.             End If  
  176.             Dim expires As DateTime  
  177.             Dim isweekint As Char  
  178.             If isweek Then  
  179.                 expires = Now.AddDays(7)  
  180.                 isweekint = "1"  
  181.             Else  
  182.                 expires = Now.AddHours(1)  
  183.                 isweekint = "0"  
  184.             End If  
  185.             '解密密匙的后8位字节 随机生成参数i  
  186.             Dim rbyte() As Byte = Encoder.GetBytes(RandomCode(8))  
  187.             Dim keyboard() As Byte = New Byte(23) {}  
  188.             autocode.CopyTo(keyboard, 0)  
  189.             '组合密匙 长度为24位  
  190.             rbyte.CopyTo(keyboard, autocode.Length)  
  191.             autocode = Nothing  
  192.             Dim exp As String = Now.Ticks.ToString("D", Format)  
  193.             '加密字符串  
  194.             Dim value As String = DesEncrypt(String.Format(Format, "{4}{0}{1}{2}|{3}", isweekint, userid, username, exp, MD5Public(String.Format(Format, "{0}{5}{1}{2}:rayyu.{3};{4}", userid, exp, username, CookieDomain, isweek, CustomCode))), keyboard)  
  195.             keyboard = Nothing  
  196.             Dim key As String = ENChar(System.BitConverter.ToString(rbyte)) '混淆参数i  
  197.             rbyte = Nothing  
  198.             '写入cookie  
  199.             Dim cookie As New HttpCookie(CookieName)  
  200.             cookie.Values.Add("n", username)  
  201.             cookie.Values.Add("u", value)  
  202.             cookie.Values.Add("i", key)  
  203.             cookie.Path = "/"  
  204.             cookie.Expires = expires  
  205.             cookie.Domain = CookieDomain  
  206.             HttpContext.Current.Response.Cookies.Set(cookie)  
  207.         End Sub  
  208.         ''' <summary>  
  209.         ''' TripleDESC解密  
  210.         ''' </summary>  
  211.         ''' <param name="strText">待解密字符串</param>  
  212.         ''' <param name="key">密匙</param>  
  213.         ''' <returns></returns>  
  214.         ''' <remarks></remarks>  
  215.         Protected Friend Shared Function DesDecrypt(ByVal strText As StringByVal key As Byte()) As String  
  216.             Try  
  217.                 Using provider As New System.Security.Cryptography.TripleDESCryptoServiceProvider()  
  218.                     provider.Key = key  
  219.                     provider.Mode = System.Security.Cryptography.CipherMode.ECB  
  220.                     Dim inputBuffer As Byte() = Convert.FromBase64String(strText)  
  221.                     Return Encoder.GetString(provider.CreateDecryptor().TransformFinalBlock(inputBuffer, 0, inputBuffer.Length)).Trim  
  222.                 End Using  
  223.             Catch ex As CryptographicException  
  224.                 Return String.Empty  
  225.             Catch ex As ArgumentNullException  
  226.                 Return String.Empty  
  227.             Catch ex As DecoderFallbackException  
  228.                 Return String.Empty  
  229.             Catch ex As ArgumentException  
  230.                 Return String.Empty  
  231.             Catch ex As FormatException  
  232.                 Return String.Empty  
  233.             End Try  
  234.         End Function  
  235.         ''' <summary>  
  236.         ''' TripleDESC加密  
  237.         ''' </summary>  
  238.         ''' <param name="strText">待加密字符串</param>  
  239.         ''' <param name="key">密匙</param>  
  240.         ''' <returns></returns>  
  241.         ''' <remarks></remarks>  
  242.         Protected Friend Shared Function DesEncrypt(ByVal strText As StringByVal key As Byte()) As String  
  243.             Try  
  244.                 Using provider As New System.Security.Cryptography.TripleDESCryptoServiceProvider()  
  245.                     provider.Key = key  
  246.                     provider.Mode = System.Security.Cryptography.CipherMode.ECB  
  247.                     Dim bytes As Byte() = Encoder.GetBytes(strText)  
  248.                     Return Convert.ToBase64String(provider.CreateEncryptor().TransformFinalBlock(bytes, 0, bytes.Length))  
  249.                 End Using  
  250.            Catch ex As CryptographicException  
  251.             Return String.Empty  
  252.         Catch ex As ArgumentNullException  
  253.             Return String.Empty  
  254.         Catch ex As DecoderFallbackException  
  255.             Return String.Empty  
  256.         Catch ex As ArgumentException  
  257.             Return String.Empty  
  258.         Catch ex As FormatException  
  259.             Return String.Empty  
  260.         End Try  
  261.     End Function  
  262.         ''' <summary>  
  263.         ''' md5加密  
  264.         ''' </summary>  
  265.         ''' <param name="str">待加密字符串</param>  
  266.         ''' <returns>返回加密后字符串</returns>  
  267.         ''' <remarks></remarks>  
  268.         Private Shared Function MD5Public(ByVal str As StringAs String  
  269.             Dim returnx As String = "0000000000000000"  
  270.             If str IsNot Nothing AndAlso str IsNot String.Empty Then  
  271.                 Try  
  272.                     Using m As New System.Security.Cryptography.MD5CryptoServiceProvider()  
  273.                         Dim MDByte As Byte() = m.ComputeHash(Encoder.GetBytes(str))  
  274.                         returnx = Strings.Replace(System.BitConverter.ToString(MDByte), "-""")  
  275.                         m.Clear()  
  276.                     End Using  
  277.             Catch ex As ObjectDisposedException  
  278.                 returnx = "0000000000000000"  
  279.                 Catch ex As ArgumentOutOfRangeException  
  280.                     returnx = "0000000000000003"  
  281.                 Catch ex As ArgumentNullException  
  282.                     returnx = "0000000000000001"  
  283.                 Catch ex As EncoderFallbackException  
  284.                     returnx = "0000000000000001"  
  285.                 Catch ex As InvalidOperationException  
  286.                     returnx = "0000000000000002"  
  287.                 End Try  
  288.             End If  
  289.             Return returnx  
  290.         End Function  
  291.         ''' <summary>  
  292.         ''' 随机数  
  293.         ''' </summary>  
  294.         ''' <remarks></remarks>  
  295.         Private Shared Randoms As New Random  
  296.         ''' <summary>  
  297.         ''' 随机字符集合  
  298.         ''' </summary>  
  299.         ''' <remarks></remarks>  
  300.         Private 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
【ASP.NET MVC系列】浅谈ASP.NET MVC 视图与控制器传递数据发布时间:2022-07-10
下一篇:
asp.net1.1/2.0的国际化方案对比发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap