[CLOSED] Sharing sessions between iframes and Javascript

More Javascript call to HTTP endpoint issues.

I have an iframe that is displaying an Anvil form, and an HTML link that is making a Javascript call to an HTTP endpoint that is calling anvil.users.logout()

I want the iframe and the Javascript call to share the same session, so that the call to logout logs them out in the form itself. There seem to be a number of things that can block this. So far this is what I have for the headers being returned from the HTTP endpoint:

r.headers['Access-Control-Allow-Origin'] = anvil.server.request.origin
r.headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
r.headers['Access-Control-Request-Method'] = '*'
r.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
r.headers['Access-Control-Allow-Credentials'] = True

And here’s the Javascript call:

$.ajax({
   url: 'https://example.anvil.app/_/api/user/logout',
   type: 'GET',
   contentType: 'text/plain',
   xhrFields: {
      withCredentials: true
   },
   crossDomain: true
});    

Some debugging code shows that the iframe and the Javascript call are not sharing the same session.

Some references suggest that the server might be marking sessions as HTTP ONLY so that they’re not available to scripts. I don’t know if that’s happening here or not, or if there’s something else I could be doing to share the sessions.

Does anyone have any ideas on what to look at?

Greater minds than mine may be more help here, but …

I don’t think they can. A session is server based. You “appear” to have two different servers - the one containing the iframe (your “normal” web page) and the Anvil server running your app inside the iframe.

If you want to share information, I think you’re going to have to pass it back and forth via API calls.

Normally web sessions are identified by a session id stored in a cookie on the client machine. Any client request that sends that cookie shares that session. I’m assuming Anvil uses that mechanism, but maybe I’m assuming too much?

I have multiple iframes that all share the same session. It’s just the Javascript I can’t get to send the right cookie (or whatever other information Anvil needs to identify which session to use).

Session cookies are generated server side and should always be secure and encrypted and therefore bound to that server. A session cookie created on one server will not be recognised (or be able to be decrypted) on another server. That would be insecure as hell!

If you’re talking about unencrypted, client-side generated cookies (which in my view are not session cookies) then I can’t help as I’ve never actually used them.

Or have I misunderstood your issue?

(edit)

Can I confirm that your other iframes (not the anvil one) are on a webserver that has something like a PHP back end? I guess what I’m getting at is how are the non-anvil cookies/sessions being created?

I think we’re talking about different cases…all my iframes (and my Javascript call) are going to the same Anvil app. So there aren’t multiple servers involved, just the one app with multiple views on it. One iframe has one form open, another opens another form, and the Javascript calls an HTTP endpoint in that same app.

I’m sorry, I misunderstood you. I read that as you had one Anvil iframe and one or more non-anvil iframes.

But all the same, if you run the same app in multiple iframes, you have multiple instances of the same app running, not multiple windows into the same session. Each one will have its own session.

Hopefully I’m not misunderstanding again :slight_smile:

That’s not what I’m seeing. I have one iframe that adds items to a shopping cart, and another that allows checking out with that cart. The iframes are on totally separate static pages. Both iframes share the same set of cookies and I just verified they do share the same session. Logging out in one iframe logs the user out in the other.

It’s just the Javascript that isn’t sending the right cookies.

Hmm, I don’t think I know enough about this to help, sorry.

A little more digging, and I’m seeing two likely session cookies for my app, named ring-session, and anvilapp. Both are both marked as HTTP Only cookies, which would explain why the Javascript call wouldn’t use them.

Having a session cookie as HTTP Only makes good sense from a security standpoint, sadly, so it doesn’t look like I’ll be able to do what I’m trying to do. At least not with standard sessions.

Hi,

What you’re seeing is a deliberate feature, to protect against Cross-Site Request Forgery (XSRF). XSRF is when some third-party webpage makes a request to an HTTP endpoint of an app you’re already logged into, asking it to do something malicious. If you don’t protect against XSRF, any web page you visit while logged into an app can call HTTP endpoints as if it were you!

We protect against this by executing HTTP endpoints for Anvil apps in an isolated session (ie separate from any session running in the same web browser), unless the request was made from your app’s domain. (The HTTP Origin header tells us where a request came from.)

This means that the page outside your iframe cannot affect your Anvil session (eg by logging you out), although if Javascript embedded in your Anvil app hits an HTTP endpoint on the same app, it has access to your session.

We do plan to add a feature to explicitly disable XSRF protection for a particular HTTP endpoint. I am therefore moving this post to Feature Requests. Watch this space!

1 Like

While I support the flexibility of being able to disable XSRF protection on specific endpoints, I hope it comes with lots of visible warnings about the potential dangers of doing so. My logout case is relatively harmless, but other endpoints won’t be.