Web Connection
Force to a "old" sessionid based on user login
Gravatar is a globally recognized avatar based on your email address. Force to a "old" sessionid based on user login
  Marcel DESMET
  All
  Jan 30, 2017 @ 11:05am

Hello,

I setup a new site with the 6.0 Web connection based on the "old" webstore sample in Foxpro

What I want to do is to get back the user basket when logged in with another browser or previously disconnected. Reading wwProcess::InitSession - Manual Session management and looking at the process and session class code it seems not be easy without creation of a subclass of the session to handle this. Maybe is there something like SwitchSession() ?

Gravatar is a globally recognized avatar based on your email address. re: Force to a
  Rick Strahl
  Marcel DESMET
  Jan 30, 2017 @ 03:39pm

There's no way to really reattach to an old session. Once you abandon it it's pretty much gone.

You can manually reload a session by keeping track of the session id yourself - which you can access whenever a session is active with Session.cSessionID - then loading that session with Session::LocateSession(lcSessionId). Once the session is loaded you can unexpire the session by flipping the timestamps.

But frankly that's s funky use case and not really a good idea. The more common course of action is to not have the session expire for a long time so when the user comes back he'll still be remembered or when they log back in the session is still around and active.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Force to a
  Harvey Mushman
  Marcel DESMET
  Jan 31, 2017 @ 04:47am

I've done this sort of thing with sessions. It allowed me to remember the username (email address) when they are a returning user. I wanted this behavior to be like Googel Gamil when they ask the user do you want to "remember me".

The part about subclassing was fairly stright forward. Below is the code I used. Just remember that you need to also add function to your logout/login dialog allowing the user to tell you "it's not me" so you can manually kill the session and disconnect the cookie.

The default UserId field in wwSession is a String which has always seemed a bit strange to me. Everywhere else in my system UserId is referred to as UserPk which is an integer. But the point here is the Session once logged in contains a tie back to the User. From there you should be able to get back to where you left off in your shopping cart.

One last point, my Cookie never expires. This works if the User has logged in from the browser before but in your question you said something about remembering the user if they switch browsers and my solution will only work if the user has logged in from that other browser before so an old Session already exists with the UserId.

 FUNCTION InitSession(lcSessionCookieName, lnTimeout, llPersist)
  *********************************************************************
  LOCAL lcSessionId

  *** we can only setup the session exactly once! All
  *** other accesses are simply aborted.
  IF !ISNULL(THIS.oSession)
   RETURN THIS.oSession.oData.SessionID
  ENDIF

  IF EMPTY(lcSessionCookieName)
   lcSessionCookieName =  THIS.cSessionKey
  ENDIF
  THIS.cSessionKey = lcSessionCookieName

  lcSessionId = THIS.oRequest.GetCookie(lcSessionCookieName)

  *** Deal with SQL class here...
  #IF WWC_USE_SQL_SYSTEMFILES
   IF ISNULL(THIS.oSession )
    THIS.oSession=CREATE([WWC_SQLSESSION])
   ENDIF

   *** Use shared Sql Connections
   THIS.oSession.oSQL = THIS.oServer.oSQL
  #ELSE
   IF ISNULL(THIS.oSession )
    THIS.oSession=CREATE([WWC_SESSION])
   ENDIF
   IF TYPE("this.oServer.oConfig") = "O"
    THIS.oSession.cDataPath = ADDBS(THIS.oServer.oConfig.cSystemFilesDataPath)
   ENDIF
  #ENDIF

  *** Set timeout
  IF !EMPTY(lnTimeout)
   THIS.oSession.nSessionTimeout = lnTimeout
  ENDIF

  *** Check for Session or create a new one
  IF !THIS.oSession.IsValidSession(lcSessionId)
   *** Also log the browser and RemoteAddress - assign oRequest property
   THIS.oSession.oRequest=THIS.oRequest

   ***** Consider adding this code ******
   IF THIS.oSession.LocateSession(lcSessionId,.T.)
    lcUserId = THIS.oSession.oData.USERID
   ELSE
    * no history to persist
    lcUserId = ''
   ENDIF


   *** Nope create it -
   *** optionally use existing sessionid retrieved from cookie
   *** to allow persistant user session ids

   * lcSessionId=THIS.oSession.NewSession( ,IIF(llPersist,lcSessionId,"") )
   * revised to pass lcUserId to the New Session
   lcSessionId=THIS.oSession.NewSession( lcUserId ,IIF(llPersist,lcSessionId,"") )

   *** Web Control Page
   *** Force HTML object to add the Cookie in Header creation
   THIS.oResponse.AddCookie(lcSessionCookieName,lcSessionId,"/",;
    IIF(llPersist,"NEVER",""),"",.T.)
  ENDIF

  *** Update PRIVATE Session var if it previously exists
  SESSION = THIS.oSession

  RETURN lcSessionId

 ENDFUNC

In the above subclass, I've commented my changes from the stock InitSession. This code needs to be placed in your project Process subclass.

*************************************************************
DEFINE CLASS myProcess AS WWC_RESTPROCESS
*************************************************************

Hope this helps...

Gravatar is a globally recognized avatar based on your email address. re: Force to a old sessionid based on user login
  Marcel DESMET
  Marcel DESMET
  Jan 31, 2017 @ 01:27pm

Hello, thank you for your help ! Finaly this code do the job to trace the user activity in the session table. I also put some code on other function like additems etc.. to synchronize the baskets on all open user sessions.. ( based on the wwwthreads logon / logoff sample code )

FUNCTION OnAuthenticateUser(lcEmail, lcPassword, lcErrorMsg)


	.... some code
	
	SESSION.SetUserId(loUserBus.oData.CookieId)			


ENDFUNC 

FUNCTION LOGOUT()

	.... some code
	
	*** Force authentication to log out
	THIS.Authenticate("Logout")

	SESSION.SetField("Logout",DATETIME())			

	Response.Redirect(lcReturnUrl)

ENDFUNC
© 1996-2024