Servicestack - 在会话之间传递信息

时间:2016-12-02 12:42:42

标签: session authentication servicestack

我已经实现了自定义AuthenticateAttribute,AuthUserSession和CredentialsAuthProvider。在我的AuthenticateAttribute的Execute方法中,我做了:

public override void Execute(IRequest request, IResponse response, object requestDto)
    {
        var session = request.GetSession() as IMyCustomAuthUserSession;

        // Copy certain request headers into a dictionary on my session object
    }

我需要存储一些特殊的标题,这些标题会发送给我以供日后使用。未启用身份验证时,此操作正常。启用身份验证并且用户必须登录时,我的CredentialsAuthProvider类的TryAuthenticate方法将触发:

    public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
    {
        var session = authService.GetSession() as IMyCustomAuthUserSession;
    }

这些to方法中的会话不一样,因为我在TryAuthenticate方法中获得的会话 - 在AuthenticateAttribute.Execute方法之后触发 - 不包含我存储在那里的头文件。

特殊标题仅在第一次调用Web服务器时发送,因此我需要将它们放入TryAuthenticate方法的新会话中。

我该怎么做?

1 个答案:

答案 0 :(得分:1)

在登录之间传递会话数据将很困难,因为会话在身份验证尝试之间失效。通过使用以下命令配置AuthFeature插件,您可以选择在登录之间保留相同的会话Cookie。

Plugins.Add(new AuthFeature(...) {
    GenerateNewSessionCookiesOnAuthentication = false
});

登录时会保留相同的用户ss-id/ss-pid Cookie。

使用SessionBag在Auth Sessinos

之间保存数据

如果要在经过身份验证的用户会话之外保留数据,您可以use a SessionBag,例如:

//Save
base.SessionBag["cart"] = new Cart { ... };

//Retrieve
var cart = base.SessionBag.Get<Cart>("cart");    

在自定义Cookie下保留用户数据

另一种解决方案是在自定义Cookie下保留数据,这样在身份验证期间它不会被ServiceStack无效。

您可以注册全局请求过滤器以确保每个客户端/浏览器都具有自定义Cookie ID,例如:

GlobalRequestFilters.Add((req,res,dto) => {
    var uniqueId = SessionExtensions.CreateRandomSessionId();
    var httpRes = res as IHttpResponse;             
    httpRes.Cookies.AddPermanentCookie("my-id", uniqueId);
    req.Items["my-id"] = uniqueId; //if also needed for this request
});

然后,在后续请求中,您可以在唯一的Cookie ID下保留数据,例如:

var uniqueId = req.GetSessionParam("my-id");
var cacheKey = $"urn:Cart:{uniqueId}";
var cache = req.GetCacheClient();
cache.Set(cacheKey, new Cart { ... });

然后用以下方法检索它:

var uniqueId = req.GetSessionParam("my-id");
var cacheKey = $"urn:Cart:{uniqueId}";
var cache = req.GetCacheClient();
var cart cache.Get<Cart>(cacheKey);
相关问题