首先 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)
- Dim user As New Rayyu.User()
- If user.Online Then
- Response.Write("<br />name:" & user.Name & ",online:" & user.Online & ",id:" & user.ID)
- End If
-
-
- Dim user2 As New Rayyu.User(1, "用户名", False)
C#调用:(Rayyu 是 namespace)
- Rayyu.User user = new Rayyu.User();
- Rayyu.User user2 = new Rayyu.User(1, "用户名", false);
-
-
- if (user.Online)
- {
- Response.Write("<br />name:" + user.Name + ",online:" + user.Online + ",id:" + user.Id);
- }
VB.NET 源代码:
- Imports System.Web
- Imports System.Text.RegularExpressions
- Imports System.Text
- Imports System.Security.Cryptography
-
-
-
-
- Public Class User
- #Region "自定义参数"
-
-
-
-
- Private Const CustomCode As String = "QQ:867863456"
-
-
-
-
- Private Const CookieName As String = "userinfo"
-
-
-
-
- Private Const CookieDomain As String = ".370b.com"
-
-
-
-
- Private Shared Encoder As Encoding = Encoding.UTF8
-
-
-
-
- Private Const RegexUserName As String = "[a-zA-Z\u4e00-\u9fa5][\w\u4e00-\u9fa5]{1,19}"
-
-
-
-
- Private Shared ReadOnly Format As Globalization.CultureInfo = New System.Globalization.CultureInfo("zh-CN", True)
- #End Region
- #Region "回调参数"
-
-
-
-
- Public ReadOnly Property Online As Boolean
- Get
- Return _Online
- End Get
- End Property
- Private _Online As Boolean = False
-
-
-
-
- Public ReadOnly Property Id As Integer
- Get
- Return _Id
- End Get
- End Property
- Private _Id As Integer
-
-
-
-
- Public ReadOnly Property Name As String
- Get
- Return _Name
- End Get
- End Property
- Private _Name As String
-
-
-
-
- Public ReadOnly Property IsWeek As Boolean
- Get
- Return _IsWeek
- End Get
- End Property
- Private ReadOnly _IsWeek As Boolean
- #End Region
-
-
-
-
- Public Sub New()
-
- Dim cookie As HttpCookie = HttpContext.Current.Request.Cookies(CookieName)
- If cookie IsNot Nothing Then
-
- Dim value As String = cookie.Values("u"), key As String = cookie.Values("i"), tname As String = cookie.Values("n")
- cookie = Nothing
- 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
-
- Dim keybyte As Byte() = toByte(DEChar(key))
- If keybyte IsNot Nothing Then
- Dim autocode() As Byte
- Using m As New System.Security.Cryptography.MD5CryptoServiceProvider()
- autocode = m.ComputeHash(Encoder.GetBytes(String.Format(Format, "{0}_{2}_{1}", HttpContext.Current.Request.UserAgent, tname, CustomCode)))
- m.Clear()
- End Using
- Dim keyboard() As Byte = New Byte(keybyte.Length + autocode.Length - 1) {}
- autocode.CopyTo(keyboard, 0)
- keybyte.CopyTo(keyboard, autocode.Length)
- value = DesDecrypt(value, keyboard)
- If value.Length > 0 Then
-
- Dim values As Match = Regex.Match(value, "^(?<md5>[\w]{32})(?<isweek>[01])(?<id>[\d]{1,10})(?<name>" & RegexUserName & ")\|(?<exp>[\d]{1,19})$")
- If values.Success Then
- Dim LostDateTime As Long
- 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
-
- Me._IsWeek = (values.Groups("isweek").Value = "1")
-
- 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))
- If md5 = values.Groups("md5").Value Then
-
- Dim lostdate As Double = (Now - New DateTime(LostDateTime)).TotalMinutes
- Dim l_a As Integer
- If IsWeek Then
- l_a = 10080
- Else
- l_a = 60
- End If
- If lostdate > 0 AndAlso lostdate < l_a Then
-
- Me._Name = values.Groups("name").Value
- Me._Online = True
- If lostdate > 15 Then
-
- SetUser(Me._Id, Me._Name, Me._IsWeek, autocode)
- End If
- End If
- Else
- Me._Id = 0
- Me._Name = Nothing
- End If
- End If
- End If
- End If
- End If
- End If
- End If
- End Sub
-
-
-
-
-
-
-
- Public Sub New(ByVal userId As Integer, ByVal userName As String, ByVal isWeek As Boolean)
- SetUser(userId, userName, isWeek)
- Me._ID = userId
- Me._Name = userName
- Me._IsWeek = isWeek
- Me._Online = True
- End Sub
-
-
-
-
-
-
-
-
- Private Shared Sub SetUser(ByVal userid As Integer, ByVal username As String, ByVal isweek As Boolean, Optional ByVal autocode As Byte() = Nothing)
- If autocode Is Nothing Then
-
- Using m As New System.Security.Cryptography.MD5CryptoServiceProvider()
- autocode = m.ComputeHash(Encoder.GetBytes(String.Format(Format, "{0}_{2}_{1}", HttpContext.Current.Request.UserAgent, username, CustomCode)))
- End Using
- End If
- Dim expires As DateTime
- Dim isweekint As Char
- If isweek Then
- expires = Now.AddDays(7)
- isweekint = "1"
- Else
- expires = Now.AddHours(1)
- isweekint = "0"
- End If
-
- Dim rbyte() As Byte = Encoder.GetBytes(RandomCode(8))
- Dim keyboard() As Byte = New Byte(23) {}
- autocode.CopyTo(keyboard, 0)
-
- rbyte.CopyTo(keyboard, autocode.Length)
- autocode = Nothing
- Dim exp As String = Now.Ticks.ToString("D", Format)
-
- 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)
- keyboard = Nothing
- Dim key As String = ENChar(System.BitConverter.ToString(rbyte))
- rbyte = Nothing
-
- Dim cookie As New HttpCookie(CookieName)
- cookie.Values.Add("n", username)
- cookie.Values.Add("u", value)
- cookie.Values.Add("i", key)
- cookie.Path = "/"
- cookie.Expires = expires
- cookie.Domain = CookieDomain
- HttpContext.Current.Response.Cookies.Set(cookie)
- End Sub
-
-
-
-
-
-
-
- Protected Friend Shared Function DesDecrypt(ByVal strText As String, ByVal key As Byte()) As String
- Try
- Using provider As New System.Security.Cryptography.TripleDESCryptoServiceProvider()
- provider.Key = key
- provider.Mode = System.Security.Cryptography.CipherMode.ECB
- Dim inputBuffer As Byte() = Convert.FromBase64String(strText)
- Return Encoder.GetString(provider.CreateDecryptor().TransformFinalBlock(inputBuffer, 0, inputBuffer.Length)).Trim
- End Using
- Catch ex As CryptographicException
- Return String.Empty
- Catch ex As ArgumentNullException
- Return String.Empty
- Catch ex As DecoderFallbackException
- Return String.Empty
- Catch ex As ArgumentException
- Return String.Empty
- Catch ex As FormatException
- Return String.Empty
- End Try
- End Function
-
-
-
-
-
-
-
- Protected Friend Shared Function DesEncrypt(ByVal strText As String, ByVal key As Byte()) As String
- Try
- Using provider As New System.Security.Cryptography.TripleDESCryptoServiceProvider()
- provider.Key = key
- provider.Mode = System.Security.Cryptography.CipherMode.ECB
- Dim bytes As Byte() = Encoder.GetBytes(strText)
- Return Convert.ToBase64String(provider.CreateEncryptor().TransformFinalBlock(bytes, 0, bytes.Length))
- End Using
- Catch ex As CryptographicException
- Return String.Empty
- Catch ex As ArgumentNullException
- Return String.Empty
- Catch ex As DecoderFallbackException
- Return String.Empty
- Catch ex As ArgumentException
- Return String.Empty
- Catch ex As FormatException
- Return String.Empty
- End Try
- End Function
-
-
-
-
-
-
- Private Shared Function MD5Public(ByVal str As String) As String
- Dim returnx As String = "0000000000000000"
- If str IsNot Nothing AndAlso str IsNot String.Empty Then
- Try
- Using m As New System.Security.Cryptography.MD5CryptoServiceProvider()
- Dim MDByte As Byte() = m.ComputeHash(Encoder.GetBytes(str))
- returnx = Strings.Replace(System.BitConverter.ToString(MDByte), "-", "")
- m.Clear()
- End Using
- Catch ex As ObjectDisposedException
- returnx = "0000000000000000"
- Catch ex As ArgumentOutOfRangeException
- returnx = "0000000000000003"
- Catch ex As ArgumentNullException
- returnx = "0000000000000001"
- Catch ex As EncoderFallbackException
- returnx = "0000000000000001"
- Catch ex As InvalidOperationException
- returnx = "0000000000000002"
- End Try
- End If
- Return returnx
- End Function
-
-
-
-
- Private Shared Randoms As New Random
-
-
-
-
- Private
|
请发表评论