如何使用ServiceStack身份验证实现“记住我”

时间:2013-09-24 22:31:42

标签: authentication servicestack

我正在尝试在基于ServiceStack的项目中实现记住我功能。我不想使用基本身份验证,因为它需要在浏览器cookie中以明文形式存储密码,因此我需要提出一种易于维护和自定义的替代方法。

我理解ServiceStack自己对记住我的支持是基于缓存服务器端缓存中的IAuthSession实例,默认情况下是擦除的内存数据结构当网站重新启动时(不好)。或者,缓存也可以基于Redis或Memcached,这是更好的(缓存数据可以在网站重启后继续存在),但为图片添加了比我想要添加的更多移动部件。

相反,我想使用我自己的数据库实现此功能:

用户

  • UserID(自动增加的身份)
  • 用户名
  • 密码
  • 电子邮件
  • 名称
  • 等...

会话

  • SessionID(自动增加的身份)
  • UserID(FK to Users)
  • 的startDateTime
  • EndDateTime
  • SessionKey(GUID)

我认为事情有效的方式是:

在登录请求中,AuthService创建我的UserAuthSession类的空实例(实现IAuthSession)并调用我的自定义凭据提供程序的TryAuthenticate方法,该方法对用户进行身份验证 Users 表,使用相关用户数据填充UserAuthSession,并将新记录插入 Session 表。

然后将auth会话缓存在内存缓存中,并创建ServiceStack会话cookie(ss-idss-pid)并将其发送到浏览器。

如果用户选中记住我,则我的自定义凭据提供程序的OnAuthenticate方法会创建一个永久登录Cookie,其中包含用户的用户名和自动生成的 Sessions.SessionKey < / em>的。即使auth会话不再在缓存中,此cookie也将帮助我们跟踪用户的后续访问。

现在,假设网站已重新启动,缓存已消失,因此当我们的用户返回网站时,无法找到他的身份验证会话。 AuthenticateAttribute中的当前逻辑将用户重定向回登录屏幕,但我想改变流程,以便尝试根据我的自定义登录cookie识别用户,即:

  1. 查找从登录Cookie
  2. 中提取的用户名的最新会话记录
  3. 检查 SessionKey 是否与登录Cookie中的密钥匹配
  4. 如果匹配,那么:
    • 用户
    • 中读取用户的数据
    • 创建我的自定义身份验证会话实例,用用户数据填充并缓存它(就像初次登录时一样)
    • 使用新的 SessionKey 值插入新的会话记录
    • 向浏览器发送一个新的登录cookie,以便下次使用
  5. 如果密钥不匹配,则将用户发送回登录屏幕。
  6. 上述逻辑是否有意义?

    有没有人使用ServiceStack实现过类似的东西?

    如果我要继续这种方法,那么最好的做法是什么,不涉及创建我自己的AuthenticateAttribute自定义版本?即我可以使用哪些钩子来使用现有的ServiceStack代码构建它?

1 个答案:

答案 0 :(得分:3)

这已经为您打造了!只需使用OrmLiteCacheClient

AppHost.Configure()方法中,添加以下内容:

var dbCacheClient = new OrmLiteCacheClient {
    DbFactory = container.Resolve<IDbConnectionFactory>()
};
dbCacheClient.InitSchema();
container.Register<ICacheClient>(dbCacheClient);

我不确定添加此特定功能的时间,也许在您最初询问时它无法使用。它至少在v4.0.31中可用。