Session being overridden between requests?

Hi, I’ve got a backend running asp.net core and ServiceStack with MemoryCacheClient, custom CredentialsAuthProvider and custom user session.

I’m trying to save some data in the auth user session from a request and then use that data while gathering data for other requests.
The problem I’m running into is that what I save in the session seems to disappear by the next request, in my custom TryAuthenticateAsync() and OnAuthenticatedAsync() it seems to just be a fresh session every time(as evidenced by the CreatedAt timestamp) even tho the requests are coming from the same client.

In the request service I’m getting the session with:
var session = await base.SessionAsAsync<EhrAuthUserSession>();
setting data with:
session.AsRelative = true;
and saving with:
await base.Request.SaveSessionAsync(session);

In the auth methods getting it like this:
var session = (EhrAuthUserSession)await authService.GetSessionAsync(false, token);
and
var realSession = session as EhrAuthUserSession;

Intercepting OnSaveSessionAsync() I can see that it does get saved with the data I set but again by the next request it’s gone.

I’ve spent a lot of time combing through the docs trying to figure out why this is happening but I can’t seem to find the issue.

I’m not the one who initially set up ServiceStack in the project so it could be a configuration setting or something I’m not aware of but I can’t find anything that isn’t according to the docs.

If anyone can help me out or point in the right direction that would be great.

So a users session is stored in the registered Cache Client (i.e. MemoryCacheClient) under this cache key format:

urn:iauthsession:{sessionId}

Where sessionId is either the ss-pid cookie if RememberMe=true when authenticating otherwise ss-id.

Calling IRequest.GetSessionId() will return the right session id configured for that request, so you can check what the session stored in the cache client is with:

var sessionKey = SessionFeature.GetSessionKey(httpReq.GetSessionId());
var session = await httpReq.GetCacheClientAsync().GetAsync<IAuthSession>(sessionKey)

Which you’ll want to check after you save the session to see if the changes are being persisted.

The next thing to check is if the ss-id and ss-pid cookies are consistent in between requests required in order for requests to be associated with the existing session. You can view the cookies sent in the HTTP Request Headers using either Chrome Web Inspector, Fiddler or WireShark. They’ll need to send the same session cookies in order to resolve the same session.

Thanks for the reply.

Looking at the session key and session from cache in OnSaveSessionAsync() before and after:
await base.OnSaveSessionAsync(httpReq, Session, expiresIn, token);
It does appear to save correctly but by the next request the id is different.
If I manually put in the id from the previous request I can see the correct session with the data.

Looking in the request logs I can also see that ss-id and ss-pid does change even if the requests are coming from the same client.
Some requests do have the same ids but it seems pretty random how many have the same, might be each auth request that makes new ones?

So that does seem to be the issue.

On the frontend the requests are just send using:
var res = await client.PostAsync<T>(sender); sender being the DTO
I don’t see any cookie or id configuration anywhere.

How would I ensure that the client sends the same session cookies every time?

If ss-id/ss-pid cookies aren’t sent with the request they’ll automatically be issued with new ids.

Are you using TypeScript in a browser or C#? If you’re calling from a browser are you trying to make cross domain requests?

I’ve got an asp.net core mvc project which has a react app for part of the site, from this react app a js api sends calls to the C# part of the project and from there the ServiceStack request is sent to a asp.net core ServiceStack webservice, and that webservice is what I was talking about in my previous messages.

So it’s making Ajax calls from the browser with the JS/TypeScript JsonServiceClient which is configured to use fetch credentials by default which should be resending the same cookies with each request.

Is the API you’re trying to call in the same domain as the React App? If it’s not you can’t use SameSiteCookies.

Should be the same domain, it just sends the api calls like so: /api/messages

In that case I’d first inspect the raw HTTP Request/Response Headers to help track down why it’s not sending the cookies.

When it makes its first API Request to ServiceStack without ss-id/ss-pid Cookies, ServiceStack will respond with Set-Cookie Response Header instructions which tells the browser/client to resend these cookies on subsequent requests to the same domain, e.g:

Following that all subsequent Browser or Ajax API Requests to the same domain should resend the cookies. This is the standard contract for browser cookie behavior. Something’s wrong if it’s not resending the same cookies on subsequent requests, e.g. you’ve an Ajax request that’s automatically signing out the user and clearing the cookies, or have some extension installed prohibiting cookies, are not sending requests to the same domain, etc.

Or if you’re using Chrome on localhost you may be running into a Chrome bug, check these answers for workarounds:

From react -> C# via js api the calls all have the same cookies, but no ss-id/ss-pid.
For C# -> Webservice via servicestack, I’m trying to figure fiddler here :slight_smile:

I am indeed working on a localhost development environment atm. I’ll check those issues.
No extensions enabled.

Could the issue be that servicestack is sending the the Set-Cookie response to the C# portion but that isn’t getting passed to the browser?

The only way Cookies aren’t getting to the browser is you’ve disabled them in your AppHost by overriding SetCookieFilter or are running through a proxy that’s specifically stripping cookies.

Anyway there’s no point speculating on unlikely scenarios, integration issues like this requires checking the HTTP Request/Response headers to be able to determine what’s actually happening. Since it’s a Web App you can use Chrome’s WebInspector Network tab to inspect Request/Response headers.

In chrome’s network tab I see the that the cookies are all the same with no ids and response headers just look like this on all of them:
image
No set-cookie

It wont return Set-Cookie instructions if it’s already set, do they exist in your domain Cookies?

No ids there either no
image

ok your initial response headers is lacking the X-Powered-By Response Header suggesting the request isn’t reaching ServiceStack. Are you sure the response is coming from ServiceStack?

If you can determine you are hitting a ServiceStack API, it looks like you’re using http://localhost so you could be running into the Chrome localhost Cookie bug, can you switch to https:// and a different browser to see if it’s still not being set.

I’m definitely hitting the webservice, I can set breakpoints and hit them with my requests.

In Firefox It’s the same thing, no set-cookie response header and no ids in cookies. When I try to use https://localhost:5000/ instead of http I just get


in firefox and

in chrome

I’ll be going on weekend now, thanks for the support so far, I’ll continue on Monday.

You’ll need to either switch to use https://localhost:5001 in launchSettings.json or host them on multiple ports, e.g.

     "applicationUrl": "https://localhost:5001;http://localhost:5000",

BTW do you have the AuthFeature configured?

Getting it running on https locally turned out to be a bit of a struggle but that now works.

Authfeature is enabled and works just fine besides the session issue, set up like so:

new AuthFeature (
    () => new EhrAuthUserSession(),
    new IAuthProvider[] {
    	new EhrCredentialsAuthProvider()
    }
)

Still no set-cookie header:
image

And no ids in cookies:
image

Replying directly.

This response suggests it didn’t come from ServiceStack as there’s no X-Powered-By Response Header or ss-id/pid cookies set.

Please post a screenshot of it hitting a breakpoint in a ServiceStack Service and the Request/Response Headers of that request showing the route and the Request DTO.

Even better paste the -raw output using Post Command Utils in the latest x tool, you can upgrade to the latest version with:

$ dotnet tool update -g x

And invoke your API with:

x GET https://localhost:5001 RequestDtoName -raw

Then paste the full output containing the Request/Response Headers.

The x tool doesn’t seem to want to install or update, I get this error:

The tool package could not be restored.
Tool 'x' failed to install. This failure may have been caused by:

* You are attempting to install a preview release and did not use the --version option to specify the version.
* A package by this name was found, but it was not a .NET tool.
* The required NuGet feed cannot be accessed, perhaps because of an Internet connection problem.
* You mistyped the name of the tool.

For more reasons, including package naming enforcement, visit https://aka.ms/failure-installing-tool

Here’s the breakpoint in a service:

request/response just looks like this:


image

relativeId is just the parameter for the JS api, true is the response from the servicestack webservice.

I can’t seem to see the C# -> Webservice requests anywhere, not even in fiddler. No DTOs anywhere.