WebHare community

Auth redirect loop

In a certain scenario, I’m getting a redirect loop in my site. From what I can gather, it’s restoresession.shtml that’s the culprit, redirecting me to the login page, which gets a 303 from restoresession.shtml with a redir to login page, which gets a 303 from restoresession.shtml with a redir to login page, and so on.

To reproduce this, I need to do the following:

  1. kill browser (works best with Firefox (if you let Firefox start ‘clean’ without tabs))
  2. start browser
  3. go to frontend (https://dashboard.wijverkopenuwautowel.nl) and login - no problem
  4. kill browser
  5. start browser
  6. go to frontend => redirect loop

After the first login, there are 3 cookies:

After killing the browser and getting in the redirect loop, 1 remains:

I need to remove this cookie to stop the redirect loop.

After a proper login, I can also trigger the redirect loop by deleting the 2 session cookies and refreshing.

My auth script is as follows:

STRING url := GetRequestURL();
IF (url LIKE "*/.ap/*" OR url LIKE "*/.uc/*" OR url LIKE "*/.publisher/*" OR url LIKE "*/wh_services/*")
  RETURN;

OBJECT trans := OpenPrimary();
OBJECT site := OpenSiteByName("wvuaw dashboard");
OBJECT webdesign := GetWebDesign(site->rootobject->id);
OBJECT wrdauth := webdesign->GetWRDAuthPlugin();

BOOLEAN loggedin := wrdauth->IsLoggedIn();

IF (url LIKE "*/login/")
{
  IF (loggedin)
    Redirect(webdesign->targetsite->webroot);

  RETURN;
}

IF (NOT loggedin)
{
  Redirect(webdesign->pageconfig.pages.login); // /login/
}

Any idea how to fix this?

Your screenshots are not showing the exact cookie names - they matter to diagnose. See also https://www.webhare.dev/reference/wrdauth/background

given there’s only one I’m going to presume it’s the _p cookie, and that the login cookie is missing. you’re being redirect to restoresession.shtml because the _p cookie is there, but the login cookie is missing. restoresession sets the login cookie and redirects back. you’re getting in a loop because after the back-redirect from restoresession, the login cookie still isn’t there.

we first need to establish whether this is a bug in code or whether the browser is not properly honoring the cookie set requests.

what cookies are set by restoresession.shtml? (The Set-Cookie headers, which of the _p, _j, _c and/or no suffix do they set?)

and does the browser still send them on the next request after restoresession.shtml in a Cookie header?

In the redir loop, only the _j cookie is present:

image

restoresession sets this cookie:

image

/login/ also does this, but that’s probably because restoresession returns a 303 to /login/.

In the redirect loop, restoresessions keeps setting that _j cookie.

In the redir loop, only the _j cookie is present:

Are you saying that the cookies differ between the request to restoresession and whatever came before that? Is this a cross domain issue?

The JS code

    var currentstate = domcookie.read(this.cookiename + '_c');

    if(dompack.debugflags.aut)
    {
      console.log("[aut] " + this.cookiename + "_j=" + jsstate);
      console.log("[aut] " + this.cookiename + "_c=" + currentstate);
    }
    if(!jsstate)
      return;

    if(!currentstate || currentstate.substr(0, jsstate.length) != jsstate)
    {
      location.replace('/.wrd/auth/restoresession.shtml' + getBackVar(location.href));
      return;
    }

only sends you to restoresession -on the same domain- if there’s a _c cookie. is this cookie completely gone or only sent on some requests? is the _c cookie bound to a subpath instead of just “/” as the _j cookie is above ?

Set the ‘aut’ debugflag, it might log something useful to the console

With ‘aut’:

And indeed, only a _j cookie in stoarge since _c is always null.

Console from a successful attempt (after clearing cookies and restarting FF):

From what I see:

  • successful login: both _j and _c are present. _j is a normal cookie, _c is a session cookie
  • kill Firefox, start Firefox, go to login page and immediately use Esc to prevent the redirect loop: only a _j cookie is present, as expected
  • refresh => redirect loop, and no _c cookie appears, only the _j remains

If I now remove the _j cookie, refresh and login, all goes well. The _c cookie is back.

Seems to me WebHare is confused because only the normal cookie is present and not the session cookie. I don’t see restoresession.shtml trying to set the _c cookie. Or, well, it’s trying but currentstate is null all the time.

The _c cookie is a session cookie which contains the requested userinfo for use by JavaScript. The _j cookie is a long lived cookie which is used by the JavaScript code as a hint that the current user is logged in. The presence of _j but not _c may trigger a redirect to restoresession.shtml to verify that the login session is still valid and to rebuild the _c cookie with the requested user information.

The _j and _c cookies are not marked httpOnly so JavaScript can access their contents and restore loginstate when needed even on static HTML pages.

in post 3 above you show the “Request cookies” which are not the cookies restoresession.shtml sets, but the cookies it receives. I think restoresession.shtml is setting cookies which are ignored by the browser’s cookie policy but it would be nice to be sure ,so can you check the set-cookie headers there if they have any interesting options? Is there a way to get firefox to log if and why it’s ignoring a set-cookie?

If restoresession sets the cookies but firefox doesn’t accept them, the loop makes sense. Because _j would still be set and _c would still be unset. We need to find some more information on firefox’s cookie restrictions to figure out what would actually work then, possible workarounds might include:

  • clearing the _j cookie and POST submitting it to restoresession.shtml. if we return, at least _j will be unset and not trigger a re-loop
  • a sessionstorage flag to tell that we just started the restoresession loop, so we won’ try it more than once

Can’t find any way or option to make sure I can see failed set-cookie headers, so I can’t say for sure if set-cookie is failing for some reason.

I’ve disabled all options that have something to do with blocking cookies but it doesn’t change anything.

Enabling the “Delete cookies and site data when Firefox is closed” option fixes the loop, probably because the _j cookie is also removed when closing FF.

I’ve added

    domcookie.remove(this.cookiename + '_j');

before var jsstate = domcookie.read(this.cookiename + '_j'); and that (no surprise) also prevents the loop (html.wh-wrdauth--isloggedin isn’t set anymore though).

Not really sure how to get more useful info. Perhaps there’s some (proper) code that I can change on the live server to see if it works?

before var jsstate = domcookie.read(this.cookiename + '_j'); and that (no surprise) also prevents the loop ( html.wh-wrdauth--isloggedin isn’t set anymore though).

that would be expected, but it also destroys session restoration… it’s the equivalent of just removing it.

Perhaps there’s some (proper) code that I can change on the live server to see if it works?

not sure what you mean by this.

Forcing the login to be persistent seems to at least solve it for now.

Perhaps there’s some (proper) code that I can change on the live server to see if it works?

I meant, maybe you can provide me with some code that I can hotfix on the live server to test, but that’s probably too much trial & error and bound to give me an angry client.

I have no code to test. I have no idea what the issue might be and why it seems to be specific to this instance and firefox, other than “Firefox being annoying about cookies again”

Well, it’s not only Firefox, Chrome had the same problem, but FF made for easier reproduction of the issue.

I can try to create a new simple module that triggers this problem? Would that be useful?

that might be useful. or try to adapt one of the *auth* builtin tests to trigger the issue.