Web Connection
WC 6.12 - dropping sessions
Gravatar is a globally recognized avatar based on your email address. WC 6.12 - dropping sessions
  Stein Goering
  All
  Jun 29, 2017 @ 08:43pm

After upgrading my application to Web Connection 6.12 I immediately ran into a number of issues - most notably it was asking for a logon each time I hit a page. Checking the wwSession table showed it was assigning a new Session ID for each hit so no information was being persisted.

The culprit turned out to be the revised GetUniqueID function which now returns a maximum of 16 characters regardless of the size parameter passed in. But the SessionID field is 17 characters, which under VFP means there's a space padded at the end so when InitSession tries to match the session retrieved from the cookie, it can't find an exact match and creates a new one instead.

The field size is not a problem with SQL Server varchar fields but my app has to support both back ends.

To make things work for now I just kludged this block to use 17 as the maximum instead of 16.

IF lnLength > 16
   lnLength = 16
ENDIF
But we need a way to skip that length limit if necessary. Maybe a 4th parameter to GetUniqueID called llNoSizeLimit which, if true, skips the above snippet?

--stein

Gravatar is a globally recognized avatar based on your email address. re: WC 6.12 - dropping sessions
  Rick Strahl
  Stein Goering
  Jun 29, 2017 @ 09:47pm

Change the fields to varchar.

The table structure of wwSession should be:

*** You can override this method to add additional fields to your
*** session table. Use GetField(<cFieldName>) to retrieve the value
*** from any fields you add 
CREATE TABLE ( THIS.cDataPath+THIS.cTableName ) FREE;
  (SESSIONID    varchar (17),;
   USERID      varchar (15),;
   FIRSTON     T ,;
   LASTON      T ,;
   VARS        M ,;
   BROWSER     M ,;
   IP          M ,;
   HITS		   I )

Best thing to do is kill the Session table and let it be recreated - it'll do the right thing when the table is recreated.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: WC 6.12 - dropping sessions
  Stein Goering
  Rick Strahl
  Jun 30, 2017 @ 08:59am

As noted, the field size is not a problem with SQL Server data - I'm already using varchar fields - but my app has to support both back ends. The problem is with VFP where we're stuck with fixed-size fields.

I do NOT want to change my table structures - I've customized wwsession to add my own fields (per your recommendation) plus I store the session ID in a number of supporting tables. And I've got over 100 customer sites to support. It was a total PITA to make the switch when we expanded the session field from 14 to 17 chars.

The specs for wwUtils::GetUniqueId() state that it "allows specification of a size that determines the size of the generated string between 15 and 32 characters" I need some way to enforce that behavior.

--stein

Gravatar is a globally recognized avatar based on your email address. re: WC 6.12 - dropping sessions
  Rick Strahl
  Stein Goering
  Jun 30, 2017 @ 05:23pm

Not sure why you would ever want to use the SessionID outside of the session table - isn't the dependency chain usually the opposite? The ID is supposed to be an internal feature, not something that's shared with other application components - it's an implementation detail.

Anyway the new function provides unique ids that are derived off Guids and generate random IDs which was a much requested feature so the ids aren't guessable. ID values are between 8 and 16 in length and for sessions we use the full 17.

***      Pass: lnLength = length between 8 and 16 - 16 is full Guid

If you are already sublcassing wwSession, just override the GenerateSessionId() function:

FUNCTION GenerateSessionId
RETURN PADR(GetUniqueID(16),17,"_")
ENDFUNC
or use some other way to generate the ID.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: WC 6.12 - dropping sessions
  Stein Goering
  Rick Strahl
  Jul 1, 2017 @ 12:05am

Not sure why you would ever want to use the SessionID outside of the session table - isn't the dependency chain usually the opposite? The ID is supposed to be an internal feature, not something that's shared with other application components - it's an implementation detail.

Well, I've got a couple of tables that are used to track a user's shopping cart, which need to be tied to their browser session. It seemed to me the most straightforward way to do that was to use Session.GetSessionID() and plug the value into the secondary table. I've also got a table that I use to log events for troubleshooting purposes - I need to distinguish those entries according to session - again it seemed most expedient to just use the session ID.

Sorry if I wasn't supposed to do things that way, but it's been working for 20 years and I'm not inclined to change it now. But the GenerateSessionID override you suggest is an easy enough workaround.

I'm still not sure what the point is of limiting IDs to 16 chars when the passed-in parameter specifies a longer string. I get it that 16 all you need to guarantee uniqueness, but would returning extra characters really hurt anything?

I do think if that limit is going to be in place, the GetUniqueID update should be documented as a Breaking Changeā€¦

--stein

Gravatar is a globally recognized avatar based on your email address. re: WC 6.12 - dropping sessions
  Rick Strahl
  Stein Goering
  Jul 1, 2017 @ 09:52am

The point is that there are no additional characters ?? These values are generated off GUIDs (which are 16 binary bytes) that are then pared down through parsing. The max I can get out of that is 16 characters. Anything larger and I have to start adding characters. Generally speaking shorter IDs are more desirable for space and speed so needlessly adding characters seems just wrong.

If you rely on implementation details (like the session ID) unfortunately you can get bit by changes that your dependencies introduce and that's what's happening. wwSession itself handles those implementation details assuming you updated the table structure at some point. I believe if you don't update the structure sessions won't work at all because the updates removed any sort of padding of content that would otherwise be required to match the ids.

FWIW, the better approach that I advocate (and is in the docs) is to add ids to linked table that might be using Session data and then accessing those IDs to get what you need. That way you never need to deal with the native session ID, only your own managed IDs you explicitly created.

I understand that sometimes things are easier if you just do things directly, but working off implementation details almost always ends up biting you - especially when you look at your 20 year time frame :-). wwSession has changed the way IDs are generated several times over that timeframe.

+++ Rick ---

© 1996-2017