首先 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)

  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. Dim user2 As New Rayyu.User(1, "用户名", False) '初始化(写入新用户)

C#调用:(Rayyu 是 namespace)

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

VB.NET 源代码:

  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 Integer, ByVal userName As String, ByVal 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 Integer, ByVal username As String, ByVal isweek As Boolean, Optional 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 String, ByVal 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 String, ByVal 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 String) As 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 Shared xarrChar() As Char = New Char() {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
  301. ''' <summary>
  302. ''' 生成随机数
  303. ''' </summary>
  304. ''' <returns></returns>
  305. ''' <remarks></remarks>
  306. Public Shared Function RandomCode(ByVal length As Integer) As String
  307. Dim str As String = ""
  308. Dim mlength As Integer = xarrChar.Length
  309. For i As Integer = 0 To length - 1
  310. str &= xarrChar(Randoms.Next(0, mlength))
  311. Next
  312. Return str
  313. End Function
  314. ''' <summary>
  315. ''' 16进制字符串转Byte数组
  316. ''' </summary>
  317. ''' <param name="value"></param>
  318. ''' <returns></returns>
  319. ''' <remarks></remarks>
  320. Private Shared Function toByte(ByVal value As String) As Byte()
  321. Try
  322. Dim chars As String() = value.Split("-")
  323. Dim length As Integer = chars.Length - 1
  324. Dim byte_() As Byte = New Byte(length) {}
  325. For i As Integer = 0 To length
  326. byte_(i) = Convert.ToByte(chars(i), 16)
  327. Next
  328. Return byte_
  329. Catch ex As ArgumentException
  330. Return Nothing
  331. Catch ex As FormatException
  332. Return Nothing
  333. Catch ex As OverflowException
  334. Return Nothing
  335. End Try
  336. End Function
  337. ''' <summary>
  338. ''' TripleDESC-部分密匙 字符混淆 如果要修改下面的字符 请注意修改上面的正则
  339. ''' </summary>
  340. ''' <param name="value"></param>
  341. ''' <returns></returns>
  342. ''' <remarks></remarks>
  343. Private Shared Function ENChar(ByVal value As String) As String
  344. value = Strings.Replace(value, "A", "H")
  345. value = Strings.Replace(value, "B", "G")
  346. value = Strings.Replace(value, "0", "B")
  347. value = Strings.Replace(value, "9", "A")
  348. Return value
  349. End Function
  350. ''' <summary>
  351. ''' TripleDESC-部分密匙 字符反混淆 如果要修改下面的字符 请注意修改上面的正则
  352. ''' </summary>
  353. ''' <param name="value"></param>
  354. ''' <returns></returns>
  355. ''' <remarks></remarks>
  356. Private Shared Function DEChar(ByVal value As String) As String
  357. value = Strings.Replace(value, "A", "9")
  358. value = Strings.Replace(value, "B", "0")
  359. value = Strings.Replace(value, "G", "B")
  360. value = Strings.Replace(value, "H", "A")
  361. Return value
  362. End Function
  363. End Class

C#源代码:

    1. using System;
    2. using System.Web;
    3. using System.Text.RegularExpressions;
    4. using System.Text;
    5. using System.Security.Cryptography;
    6. namespace Rayyu
    7. {
    8. /// <summary>
    9. /// 用户登录机制 支持1小时/1周状态
    10. /// </summary>
    11. /// <remarks></remarks>
    12. public class User
    13. {
    14. #region "自定义参数"
    15. /// <summary>
    16. /// 自定义字符 用于第一层加解密密匙
    17. /// </summary>
    18. /// <remarks></remarks>
    19. private const string CustomCode = "QQ:867863456";
    20. /// <summary>
    21. /// cookie名
    22. /// </summary>
    23. /// <remarks></remarks>
    24. private const string CookieName = "userinfo";
    25. /// <summary>
    26. /// Cookie作用域
    27. /// </summary>
    28. /// <remarks></remarks>
    29. private const string CookieDomain = ".370b.com";
    30. /// <summary>
    31. /// 编码
    32. /// </summary>
    33. /// <remarks></remarks>
    34. private static Encoding Encoder = Encoding.UTF8;
    35. /// <summary>
    36. /// 用户名的正则检测 我的是:首位由字母或者汉字构成,由字母、数字、下划线、和汉字的 2-20位的字符 组合而成 的
    37. /// </summary>
    38. /// <remarks></remarks>
    39. private const string RegexUserName = "[a-zA-Z\\u4e00-\\u9fa5][\\w\\u4e00-\\u9fa5]{1,19}";
    40. /// <summary>
    41. /// 区域化信息设置
    42. /// </summary>
    43. /// <remarks></remarks>
    44. private static System.Globalization.CultureInfo Format = new System.Globalization.CultureInfo("zh-CN", true);
    45. #endregion
    46. #region "回调参数"
    47. /// <summary>
    48. /// 是否在线
    49. /// </summary>
    50. /// <remarks></remarks>
    51. public  bool Online
    52. {
    53. get { return _Online; }
    54. }
    55. private  bool _Online = false;
    56. /// <summary>
    57. /// 用户ID (Online=true情况下使用)
    58. /// </summary>
    59. /// <remarks></remarks>
    60. public  int Id
    61. {
    62. get { return _Id; }
    63. }
    64. private int _Id;
    65. /// <summary>
    66. /// 用户名 (Online=true情况下使用)
    67. /// </summary>
    68. /// <remarks></remarks>
    69. public  string Name
    70. {
    71. get { return _Name; }
    72. }
    73. private string _Name;
    74. /// <summary>
    75. /// 有效期是否为7天
    76. /// </summary>
    77. /// <remarks></remarks>
    78. public bool IsWeek
    79. {
    80. get { return _isWeek; }
    81. }
    82. private bool _isWeek;
    83. #endregion
    84. /// <summary>
    85. /// 初始化用户信息(检测当前请求用户是否登录)
    86. /// </summary>
    87. /// <remarks></remarks>
    88. public User()
    89. {
    90. //读取cookie
    91. HttpCookie cookie = HttpContext.Current.Request.Cookies[CookieName];
    92. if (cookie != null)
    93. {
    94. //存在cookie
    95. string value = cookie.Values["u"];
    96. string key = cookie.Values["i"];
    97. string tname = cookie.Values["n"];
    98. cookie = null;
    99. if (tname != null && value != null && key != null && Regex.IsMatch(key, "^[1-8A-H]{2}(-[1-8A-H]{2}){7}$", System.Text.RegularExpressions.RegexOptions.None))
    100. {
    101. //存在对应键值
    102. byte[] keybyte = toByte(DEChar(key));
    103. //解密密匙的后8位字节 由参数i构成
    104. if (keybyte != null)
    105. {
    106. byte[] autocode;
    107. //解密密匙的前16位字节 由用户UserAgent,用户名,自定义字符 组合而成 的 md5
    108. using (System.Security.Cryptography.MD5CryptoServiceProvider m = new System.Security.Cryptography.MD5CryptoServiceProvider())
    109. {
    110. autocode = m.ComputeHash(Encoder.GetBytes(string.Format(Format, "{0}_{2}_{1}", HttpContext.Current.Request.UserAgent, tname, CustomCode)));
    111. }
    112. byte[] keyboard = new byte[keybyte.Length + autocode.Length];
    113. autocode.CopyTo(keyboard, 0);
    114. keybyte.CopyTo(keyboard, autocode.Length);
    115. value = DesDecrypt(value, keyboard);
    116. if (value.Length > 0)
    117. {
    118. //解密成功 第一层合法
    119. Match values = Regex.Match(value, "^(?<md5>[\\w]{32})(?<isweek>[01])(?<id>[\\d]{1,10})(?<name>" + RegexUserName + ")\\|(?<exp>[\\d]{1,19})$");
    120. if (values.Success)
    121. {
    122. long LostDateTime = 0;
    123. if (int.TryParse(values.Groups["id"].Value, out this._Id) && this._Id > 0 && long.TryParse(values.Groups["exp"].Value, out LostDateTime) && LostDateTime > 0)
    124. {
    125. //解密后的字符串格式正确
    126. this._isWeek = (values.Groups["isweek"].Value == "1");
    127. //此md5用于验证解密后的字符串 由用户id,用户名,cookie写入时间,自定义字符串 以及有效期是否是1周 组合
    128. string md5 = 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));
    129. if (md5 == values.Groups["md5"].Value)
    130. {
    131. //md5正常
    132. double lostdate = (DateTime.Now - new DateTime(LostDateTime)).TotalMinutes;
    133. int l_a = 0;
    134. if (_isWeek)
    135. {
    136. l_a = 10080;
    137. }
    138. else
    139. {
    140. l_a = 60;
    141. }
    142. if (lostdate > 0 && lostdate < l_a)
    143. {
    144. //cookie在有效期内
    145. this._Name = values.Groups["name"].Value;
    146. this._Online = true;
    147. if (lostdate > 15)
    148. {
    149. //cookie以写入超过15分钟,从新写入1次cookie
    150. SetUser(this._Id, this._Name, this._isWeek, autocode);
    151. }
    152. }
    153. }
    154. else
    155. {
    156. this._Id = 0;
    157. this._Name = null;
    158. }
    159. }
    160. }
    161. }
    162. }
    163. }
    164. }
    165. }
    166. /// <summary>
    167. /// 初始化(写入新用户)
    168. /// </summary>
    169. /// <param name="userid">用户id</param>
    170. /// <param name="username">用户名</param>
    171. /// <param name="isweek">是否保持一周登录状态</param>
    172. /// <remarks></remarks>
    173. public User(int userId, string userName, bool isWeek)
    174. {
    175. SetUser(userId, userName, isWeek);
    176. this._Id = userId;
    177. this._Name = userName;
    178. this._isWeek = isWeek;
    179. this._Online = true;
    180. }
    181. /// <summary>
    182. /// 写入用户
    183. /// </summary>
    184. /// <param name="userid">用户id</param>
    185. /// <param name="username">用户名</param>
    186. /// <param name="isweek">是否保持一周登录状态</param>
    187. /// <param name="autocode"></param>
    188. /// <remarks></remarks>
    189. private static void SetUser(int userid, string username, bool isweek, byte[] autocode = null)
    190. {
    191. if (autocode == null)
    192. {
    193. //解密密匙的前16位字节 由用户UserAgent,用户名,自定义字符 组合而成 的 md5
    194. using (System.Security.Cryptography.MD5CryptoServiceProvider m = new System.Security.Cryptography.MD5CryptoServiceProvider())
    195. {
    196. autocode = m.ComputeHash(Encoder.GetBytes(string.Format(Format,"{0}_{2}_{1}", HttpContext.Current.Request.UserAgent, username, CustomCode)));
    197. m.Clear();
    198. }
    199. }
    200. DateTime expires = default(DateTime);
    201. char isweekint;
    202. if (isweek)
    203. {
    204. expires = DateTime.Now.AddDays(7);
    205. isweekint = '1';
    206. }
    207. else
    208. {
    209. expires = DateTime.Now.AddHours(1);
    210. isweekint = '0';
    211. }
    212. //解密密匙的后8位字节 随机生成参数i
    213. byte[] rbyte = Encoder.GetBytes(RandomCode(8));
    214. byte[] keyboard = new byte[24];
    215. autocode.CopyTo(keyboard, 0);
    216. //组合密匙 长度为24位
    217. rbyte.CopyTo(keyboard, autocode.Length);
    218. autocode = null;
    219. string exp = DateTime.Now.Ticks.ToString("D", Format);
    220. //加密字符串
    221. string value = 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);
    222. keyboard = null;
    223. string key = ENChar(System.BitConverter.ToString(rbyte));
    224. //混淆参数i
    225. rbyte = null;
    226. //写入cookie
    227. HttpCookie cookie = new HttpCookie(CookieName);
    228. cookie.Values.Add("n", username);
    229. cookie.Values.Add("u", value);
    230. cookie.Values.Add("i", key);
    231. cookie.Path = "/";
    232. cookie.Expires = expires;
    233. cookie.Domain = CookieDomain;
    234. HttpContext.Current.Response.Cookies.Set(cookie);
    235. }
    236. /// <summary>
    237. /// TripleDESC解密
    238. /// </summary>
    239. /// <param name="strText">待解密字符串</param>
    240. /// <param name="key">密匙</param>
    241. /// <returns></returns>
    242. /// <remarks></remarks>
    243. protected static internal string DesDecrypt(string strText, byte[] key)
    244. {
    245. try
    246. {
    247. using (System.Security.Cryptography.TripleDESCryptoServiceProvider provider = new System.Security.Cryptography.TripleDESCryptoServiceProvider())
    248. {
    249. provider.Key = key;
    250. provider.Mode = System.Security.Cryptography.CipherMode.ECB;
    251. byte[] inputBuffer = Convert.FromBase64String(strText);
    252. return Encoder.GetString(provider.CreateDecryptor().TransformFinalBlock(inputBuffer, 0, inputBuffer.Length)).Trim();
    253. }
    254. }
    255. catch(CryptographicException){
    256. return string.Empty;
    257. }
    258. catch(ArgumentNullException){
    259. return string.Empty;
    260. }
    261. catch(DecoderFallbackException){
    262. return string.Empty;
    263. }
    264. catch(ArgumentException){
    265. return string.Empty;
    266. }
    267. catch(FormatException){
    268. return string.Empty;
    269. }
    270. }
    271. /// <summary>
    272. /// TripleDESC加密
    273. /// </summary>
    274. /// <param name="strText">待加密字符串</param>
    275. /// <param name="key">密匙</param>
    276. /// <returns></returns>
    277. /// <remarks></remarks>
    278. protected static internal string DesEncrypt(string strText, byte[] key)
    279. {
    280. try
    281. {
    282. using (System.Security.Cryptography.TripleDESCryptoServiceProvider provider = new System.Security.Cryptography.TripleDESCryptoServiceProvider())
    283. {
    284. provider.Key = key;
    285. provider.Mode = System.Security.Cryptography.CipherMode.ECB;
    286. byte[] bytes = Encoder.GetBytes(strText);
    287. return Convert.ToBase64String(provider.CreateEncryptor().TransformFinalBlock(bytes, 0, bytes.Length));
    288. }
    289. }
    290. catch (CryptographicException)
    291. {
    292. return string.Empty;
    293. }
    294. catch (ArgumentNullException)
    295. {
    296. return string.Empty;
    297. }
    298. catch (DecoderFallbackException)
    299. {
    300. return string.Empty;
    301. }
    302. catch (ArgumentException)
    303. {
    304. return string.Empty;
    305. }
    306. catch (FormatException)
    307. {
    308. return string.Empty;
    309. }
    310. }
    311. /// <summary>
    312. /// md5加密
    313. /// </summary>
    314. /// <param name="str">待加密字符串</param>
    315. /// <returns>返回加密后字符串</returns>
    316. /// <remarks></remarks>
    317. private static string MD5Public(string str)
    318. {
    319. using (System.Security.Cryptography.MD5CryptoServiceProvider m = new System.Security.Cryptography.MD5CryptoServiceProvider())
    320. {
    321. byte[] MDByte = m.ComputeHash(Encoder.GetBytes(str));
    322. return System.BitConverter.ToString(MDByte).Replace("-", "");
    323. }
    324. }
    325. /// <summary>
    326. /// 随机数
    327. /// </summary>
    328. /// <remarks></remarks>
    329. private static Random Randoms = new Random();
    330. /// <summary>
    331. /// 随机字符集合
    332. /// </summary>
    333. /// <remarks></remarks>
    334. private static char[] xarrChar = new char[] {
    335. '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
    336. };
    337. /// <summary>
    338. /// 生成随机数
    339. /// </summary>
    340. /// <returns></returns>
    341. /// <remarks></remarks>
    342. public static string RandomCode(int length)
    343. {
    344. string str = "";
    345. int mlength = xarrChar.Length;
    346. for (int i = 0; i < length; i++)
    347. {
    348. str += xarrChar[Randoms.Next(0, mlength)];
    349. }
    350. return str;
    351. }
    352. /// <summary>
    353. /// 16进制字符串转Byte数组
    354. /// </summary>
    355. /// <param name="value"></param>
    356. /// <returns></returns>
    357. /// <remarks></remarks>
    358. private static byte[] toByte(string value)
    359. {
    360. try
    361. {
    362. string[] chars = value.Split('-');
    363. int length = chars.Length;
    364. byte[] byte_ = new byte[length];
    365. for (int i = 0; i < length; i++)
    366. {
    367. byte_[i] = Convert.ToByte(chars[i], 16);
    368. }
    369. return byte_;
    370. }
    371. catch (ArgumentException){
    372. return null;
    373. }
    374. catch (FormatException){
    375. return null;
    376. }
    377. catch (OverflowException){
    378. return null;
    379. }
    380. }
    381. /// <summary>
    382. /// TripleDESC-部分密匙 字符混淆 如果要修改下面的字符 请注意修改上面的正则
    383. /// </summary>
    384. /// <param name="value"></param>
    385. /// <returns></returns>
    386. /// <remarks></remarks>
    387. private static string ENChar(string value)
    388. {
    389. value = value.Replace( "A", "H");
    390. value = value.Replace( "B", "G");
    391. value = value.Replace( "0", "B");
    392. value = value.Replace( "9", "A");
    393. return value;
    394. }
    395. /// <summary>
    396. /// TripleDESC-部分密匙 字符反混淆 如果要修改下面的字符 请注意修改上面的正则
    397. /// </summary>
    398. /// <param name="value"></param>
    399. /// <returns></returns>
    400. /// <remarks></remarks>
    401. private static string DEChar(string value)
    402. {
    403. value = value.Replace( "A", "9");
    404. value = value.Replace( "B", "0");
    405. value = value.Replace( "G", "B");
    406. value = value.Replace( "H", "A");
    407. return value;
    408. }
    409. }
    410. }

Asp.Net使用加密cookie代替session验证用户登录状态 源码分享的更多相关文章

  1. easyui datagrid 禁止选中行 EF的增删改查(转载) C# 获取用户IP地址(转载) MVC EF 执行SQL语句(转载) 在EF中执行SQL语句(转载) EF中使用SQL语句或存储过程 .net MVC使用Session验证用户登录 PowerDesigner 参照完整性约束(转载)

    easyui datagrid 禁止选中行   没有找到可以直接禁止的属性,但是找到两个间接禁止的方式. 方式一: //onClickRow: function (rowIndex, rowData) ...

  2. .net MVC使用Session验证用户登录(转载)

    .net MVC使用Session验证用户登录   用最简单的Session方式记录用户登录状态 1.添加DefaultController控制器,重写OnActionExecuting方法,每次访问 ...

  3. Django 用Session和Cookie分别实现记住用户登录状态

    简介 由于http协议的请求是无状态的.故为了让用户在浏览器中再次访问该服务端时,他的登录状态能够保留(也可翻译为该用户访问这个服务端其他网页时不需再重复进行用户认证).我们可以采用Cookie或Se ...

  4. 用Cookie和Session实现用户登录 函数

    由于网页是一种无状态的连接程序,你无法得知用户的浏览状态,必须通过Cookie或Session记录用户的有关信息. Cookie: 是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制. PHP透 ...

  5. 【4】 .net MVC使用Session验证用户登录

    用最简单的Session方式记录用户登录状态 1.添加DefaultController控制器,重写OnActionExecuting方法,每次访问控制器前触发 public class Defaul ...

  6. 【wpf WebBrowser 清空网站的Cookie&Session 清空用户登录状态】

    最近做项目遇到了一个说小不小,说大不大的问题,那就是在WebBrowser中清空网站上用户的登陆状态, 一开始心想,那不就清空cookies就行啦,那么简单的事情,百度一下 …… …… 是的,正如你们 ...

  7. 基于cookie的用户登录状态管理

    cookie是什么 先来花5分钟看完这篇文章:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies 看完上文,相信大家对cookie已经有 ...

  8. MVC4项目中验证用户登录一个特性就搞定

    在开发过程中,需要用户登陆才能访问指定的页面这种功能,微软已经提供了这个特性. // 摘要: // 表示一个特性,该特性用于限制调用方对操作方法的访问. [AttributeUsage(Attribu ...

  9. MVC4验证用户登录特性实现方法

    在开发过程中,需要用户登陆才能访问指定的页面这种功能,微软已经提供了这个特性. // 摘要: // 表示一个特性,该特性用于限制调用方对操作方法的访问. [AttributeUsage(Attribu ...

随机推荐

  1. elicpse

    摘自http://blog.csdn.net/bug_love/article/details/72636505 eclipse error pages打红X的解决方法 我每次建一个Maven项目转为 ...

  2. 软工网络15团队作业8——Beta阶段敏捷冲刺(用户使用调查报告)

    一.项目概述 1.项目名称 考研必背 2.项目简介 微信小程序,帮助考研学生记忆单词. 3.项目预期达到目标 用户无需下载app,仅通过微信小程序就可以达到背单词的目的,并且能够制定背单词的计划. 4 ...

  3. pyqt5 eric6

    1 安装Anaconda3 2 python环境变量改为Anaconda3中python 3 pip安装pyqt5 ,pip安装pyqt5-tool 其中tool中包含eric6 ui文件必须使用的d ...

  4. Nagios学习笔记

    1 Nagios功能 1.1  监控工具 1.2  可以监控主机/服务或者资源 1.3  四种状态值 OK,WARNING,CRITICAL,UNKNOWN CPU:90%(CRITICAL),80% ...

  5. Webpack简易入门教程

    <!-- 其实网上关于webpack的教程已经很多了,但是本人在学习过程中发现很多教程有错误,或者写的很不全面,结果做的过程出现各种各样的问题,对新手不但不友好还会让人浪费很多不必要的时间.所以 ...

  6. 【刷题】BZOJ 3551 [ONTAK2010]Peaks加强版

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

  7. 从商用到开源:15个维度,全面剖析DB2与MySQL数据库的差异

    随着MySQL数据库的应用越来越广泛,DB2向MySQL数据库的迁移需求也越来越多.进行数据库之间迁移的时候,首先遇到的并且也是最基本最重要的就是两种数据库数据类型之间的转换. 相关阅读: 从商用到开 ...

  8. Codeforces 633C Spy Syndrome 2 | Trie树裸题

    Codeforces 633C Spy Syndrome 2 | Trie树裸题 一个由许多空格隔开的单词组成的字符串,进行了以下操作:把所有字符变成小写,把每个单词颠倒过来,然后去掉单词间的空格.已 ...

  9. kafka问题集(三)ISR缺失

    仅个人实践所得,若是有误,欢迎指出. 一.场景 kafka集群中某一节点(N-10)的CPU利用率大于整个集群的平均水平,且达到报警值.使用top命令后台查看时发现是kafka服务导致CPU利用率高. ...

  10. 洛谷 P3197 [HNOI2008]越狱 解题报告

    P3197 [HNOI2008]越狱 题目描述 监狱有连续编号为\(1-N\)的\(N\)个房间,每个房间关押一个犯人,有\(M\)种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可 ...