0

我正在使用很棒的 ServiceStack 来实现我的 REST 后端,它为两个用 Xamarin 编写的 iPhone 应用程序提供服务。一切都很好,但是当两个应用程序安装在同一台设备上时,我很难让会话正常工作!

问题是,如果我登录其中一个应用程序,第二个应用程序将通过身份验证,并且由于下面的“isCurrentUserAuthenticated()”方法而不需要我登录。

我将 cookie 与我的请求一起传递以模仿浏览器并确保用户不必每次都传递他的凭据,但我猜问题是 ServiceStack 可能会看到来自同一 IP 的两个身份验证请求,因此它使用第一个对它们进行身份验证身份验证请求成功。

注意:这两个应用程序访问相同的数据库和 UserAuth 表,但每个应用程序都支持不同的用户角色。

修复它的唯一方法是从第二个应用程序中注销,以便用户可以使用他的凭据再次登录以使一切正常。

你能帮忙吗?

这是到目前为止的代码:

public static class BLL
{
    public static JsonServiceClient ServiceClient { get; set; }

    public static string HostUri = "http://test.elasticbeanstalk.com";
    public static string HostDomain = "test.elasticbeanstalk.com";

    static BLL ()
    {
        string ss_id = ConfigRepository.GetConfigString ("ss-id");
        string ss_pid = ConfigRepository.GetConfigString ("ss-pid");

        ServiceClient = new  JsonServiceClient (HostUri);

        ServiceClient.CookieContainer.Add (new Cookie ("ss-id", ss_id, "/", HostDomain));
        ServiceClient.CookieContainer.Add (new Cookie ("ss-pid", ss_pid, "/", HostDomain));
    }


    public static async Task<bool> isCurrentUserAuthenticated ()
    {
        bool result = false;

        try {

            Authenticate authRequest = new Authenticate ();

            // Restore the cookie
            var response = await ServiceClient.PostAsync<AuthenticateResponse> (authRequest);

            NSUserDefaults.StandardUserDefaults.SetString (response.UserId, "UserId");
            NSUserDefaults.StandardUserDefaults.Synchronize ();

            result = true;

        } catch (Exception Ex) {
            result = false;
        }

        return result;
    }

    public static async Task<AuthenticateResponse> Login (string userName, string password)
    {
        Authenticate authRequest = new Authenticate () {
            provider = "credentials",
            UserName = userName,
            Password = password,
            RememberMe = true,
        };

        var response = await ServiceClient.PostAsync<AuthenticateResponse> (authRequest);

        var cookies = ServiceClient.CookieContainer.GetCookies (new Uri (HostUri));

        if (cookies != null) {
            var ss_id = cookies ["ss-id"].Value;
            var ss_pid = cookies ["ss-pid"].Value;

            if (!ss_id.IsNullOrEmpty ()) {
                int r = ConfigRepository.AddConfigKey ("ss-id", ss_id);
                System.Diagnostics.Debug.WriteLine ("ss-id " + ss_id.ToString ());
            }
            if (!ss_pid.IsNullOrEmpty ()) {
                int r = ConfigRepository.AddConfigKey ("ss-pid", ss_pid);
                System.Diagnostics.Debug.WriteLine ("ss-pid " + ss_pid.ToString ());
            }
        }

        NSUserDefaults.StandardUserDefaults.SetString (response.UserId, "UserId");
        NSUserDefaults.StandardUserDefaults.Synchronize ();


        return response;
    }

    public static async Task<AuthenticateResponse> Logout ()
    {
        Authenticate authRequest = new Authenticate () {
            provider = "logout"
        };

        var response = await ServiceClient.PostAsync<AuthenticateResponse> (authRequest);
        return response;
    }
}
4

1 回答 1

1

问题是因为您将相同的会话 Cookie 与共享的 ServiceClient 实例一起使用,该实例最终引用了相同的经过身份验证的用户会话。

ServiceStack 会话仅基于客户端 cookie 指定的会话标识符 (ss-id/ss-pid),如果您使用相同的 cookie,您将引用相同的经过身份验证的用户会话,它们不受 IP 地址或任何东西的影响别的。

如果您想以另一个用户身份进行身份验证,请使用 ServiceClient 的新实例(因此它不使用现有的 Sessions Cookie)。

于 2015-06-22T00:13:53.437 回答