简体   繁体   English

ServiceStack RememberMe不使用AngularJS在Azure上工作 - 会话超时太快

[英]ServiceStack RememberMe not working on Azure with AngularJS - Sessions Time Out Too Quickly

We've got an Angular admin site up on an Azure VM. 我们在Azure VM上安装了一个Angular管理站点。 The API is build out using ServiceStack, and we've got a problem where when we login and say "Remember Me", our users aren't getting remembered. API是使用ServiceStack构建的,我们遇到了一个问题,当我们登录并说“记住我”时,我们的用户不会被记住。

Here's our AppHost plugin bit. 这是我们的AppHost插件位。

Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[]
    {
        // it seems as though order matters here. If these are reversed, CredentialsAuth doesn't work.
        new CustomCredentialsAuthProvider(container),
        new CustomBasicAuthProvider(container)
    })
    {
        HtmlRedirect = "~/login.html"
    });

And in Angular we initialize our credentials 在Angular中,我们初始化了我们的凭据

    $scope.credentials = {
        userName: '',
        password: '',
        rememberMe: false
    };
    $scope.login = function (credentials) {

        if (!$scope.signinForm.$valid) {
            $scope.submitted = true;
            toaster.pop(nullFieldAlert);
            return;
        }

        authService.save(credentials,

            // Success
            function (data) {
                $rootScope.authenticated = true;
                history.back();
            },

            // Failure
            function (e) {
                handleErrors(e);
            });
    };

and then when the user logs in, they have the option to change rememberMe = true; 然后当用户登录时,他们可以选择更改rememberMe = true;

Unfortunately our session expires within minutes (and sometimes seconds) with or without rememberMe being set. 不幸的是,无论是否设置了rememberMe,我们的会话都会在几分钟(有时是几秒)内到期。

What magic do we need to do in order to get sessions to last > 3 minutes on Azure, and get RememberMe working? 为了让Azure上的会话持续> 3分钟,我们需要做些什么,并让RememberMe工作?

Sessions Timing Out 会议时间安排

Your concern is that your sessions are expiring prematurely. 您担心的是您的会话过早到期。 This is something that you should test independently of AngularJS, because as I note below, I suspect the problem is AngularJS related. 这是你应该独立于AngularJS测试的东西,因为正如我在下面提到的,我怀疑问题与AngularJS有关。

You should directly authenticate with your ServiceStack Api from your browser: You can do this by navigating to: 您应该直接从浏览器使用ServiceStack Api进行身份验证:您可以通过导航到以下内容来执行此操作:

<your-api-url>/Auth?UserName=username&Password=password&x-http-method-override=POST

Replacing username and password as appropriate. 根据需要替换usernamepassword That should get you a valid session. 这应该会让你有效的会话。

Then you should confirm that you have a valid session by checking for the ss-id cookie in your browsers Developer Console. 然后,您应该通过在浏览器开发者控制台中检查ss-id cookie来确认您有一个有效的会话。

Make some requests for data to your secure service with this session, determine how long you can access this data for before the session expires. 使用此会话向安全服务请求数据,确定在会话到期之前可以访问此数据的时间。 I suspect that direct interaction in this way doesn't fail, and rather your issue is caused when you use AngularJS. 我怀疑以这种方式直接交互不会失败,而是当您使用AngularJS时导致问题。

Loosing $rootScope.authenticated state 丢失$rootScope.authenticated状态

I may be spitballing here because people build their AngularJS application in many different and exciting ways, and this is my interpretation of the partial code you have provided. 我可能会在这里喋喋不休,因为人们以许多不同且令人兴奋的方式构建他们的AngularJS应用程序,这是我对您提供的部分代码的解释。

I think this issue may be to do with how you recording your client side authentication state using AngularJS, rather than a ServiceStack issue. 我认为这个问题可能与您使用AngularJS记录客户端身份验证状态的方式有关,而不是ServiceStack问题。

When your AuthService sends the credentials to ServiceStack for authentication, it will do so using Angular's $http Service. 当您的AuthService将凭据发送到ServiceStack进行身份验证时,它将使用Angular的$http服务执行此操作。 ServiceStack will reply with a valid session cookie, given that your credentials were valid. 鉴于您的凭据有效,ServiceStack将使用有效的会话cookie进行回复。 This session cookie will be sent by Angular for any of the requests that follow. Angular将针对以下任何请求发送此会话cookie。

// Success
function (data) {
    $rootScope.authenticated = true;
    history.back(); // $rootScope on the other page won't be set when you go back
}

However it looks like you are determining authentication state based on the variable authenticated in your $rootScope . 但是,您似乎正在根据$rootScope authenticated的变量确定身份验证状态。 So once you successfully authenticate you set that variable. 因此,一旦您成功验证您设置该变量。 But the problem is you are loosing this state, by navigating to the previous page using history.back() , because this isn't within the scope of login.html , the $rootScope value you set no longer exists. 但问题是你失去了这种状态,通过使用history.back()导航到上一页,因为这不在login.html的范围内,你设置的$rootScope值不再存在。 So if you rely on this to determine if you are logged in, it won't work. 因此,如果您依赖于此来确定您是否已登录,则无法使用。

What you need to do is restore your $rootScope.authenticated value when the application is started. 您需要做的是在应用程序启动时恢复$rootScope.authenticated值。 See my previous answer on this issue , which discusses how to keep track of the session. 请参阅我之前关于此问题的答案,该问题讨论了如何跟踪会话。

Application Pool Recycling 应用程序池回收

If it transpires your sessions are expiring prematurely, after testing, and you are using In-Memory caching in ServiceStack (default), be aware that if the ApplicationPool of your service is recycled by the IIS host then the cache data will also be destroyed. 如果您的会话过早地过期,在测试之后,并且您在ServiceStack中使用In-Memory缓存(默认),请注意,如果IIS主机回收了您的服务的ApplicationPool ,则缓存数据也将被销毁。 But for this to be happening frequently is unusual. 但对于这种情况经常发生是不寻常的。

You could log out in your Application_Start event in global.aspx to note the frequency of recycling. 您可以在global.aspx中的Application_Start事件中注销,以记录回收的频率。

This answer of mine here touches on the recycling of the application pool. 我在这里的答案涉及应用程序池的回收。

I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM