#1 2020-06-16 10:38:04

tomek
Member
Registered: 2017-10-24
Posts: 46

Custom User/Session properties on server side

Hi
I'm trying to store some custom data for logged user, which will persist as long as session is valid (method-based server).
I've tried to inherit TSQLAuthUser:

  TMySQLAuthUser = class (TSQLAuthUser)
  protected
    fMyPropert: RawUTF8;
  published
    property MyPropert: RawUTF8 read fMyPropert write fMyPropert;
  end;

but it appeared, that retrieving user with SessionGetUser returns a copy of user, so setting any property won't persist.
I've tried to retrieve user directly from Sessions.User and it actually work, but I'm afraid it is not safe way.

Is there any other reliable way to store some custom data related to logged user/session?

BTW I've tried to store it in TSQLAuthUser.Data, but it doesn't work at all - data set in Data at TMyAuth.GetUser are lost. Is it expected behaviour?

Regards, Tomek

Offline

#2 2020-06-16 11:03:22

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: Custom User/Session properties on server side

How did you define your model?

Data property is set in TAuthSession.Create unless rsoGetUserRetrieveNoBlobData option is set (not by default).
So if you put some custom Data in your GetUser() method it will be overriden then retrieved again later.

Offline

#3 2020-06-16 11:27:46

tomek
Member
Registered: 2017-10-24
Posts: 46

Re: Custom User/Session properties on server side

Model is empty: TSQLModel.Create([]);

Setting Data property or custom property in GetUser() method was for test purposes. The goal is to set some custom data after successful login in a published server method, and then access this data in other server published methods.

Offline

#4 2020-06-16 11:57:22

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: Custom User/Session properties on server side

You have to put the overriden class TMySQLAuthUser in the model, otherwise it will use default TSQLAuthUser...

Offline

#5 2020-06-16 13:03:26

tomek
Member
Registered: 2017-10-24
Posts: 46

Re: Custom User/Session properties on server side

As I wrote at original message it's actually working (with empty model):

  TMyMethodsServer= class(TSQLRestServerFullMemory)
  protected
  private
  public
  published
    procedure SetCustomProp(Ctxt: TSQLRestServerURIContext);
  end;

procedure TMyMethodsServer.SetCustomProp(Ctxt: TSQLRestServerURIContext);
var
 i: Integer;
begin
  for i := 0 to fSessions.Count-1 do
    with TAuthSession(fSessions.List[i]) do
    if IDCardinal = Ctxt.Session then begin
      (User as TMySQLAuthUser).MyPropert:= 'test';
      Break;
    end;
  Ctxt.Results(['["ok"]']);
end;

The question is: Is this the right way to set this custom property or there is better (safe) way to do this?

Offline

#6 2020-06-16 13:37:37

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: Custom User/Session properties on server side

Your code is not thread-safe.
If a session is created or deleted in another thread, from another client connection, then you could have an access violation.

What do you want to store in this TSQLAuthUser property?
If it is application-specific data, don't mess with the session, but use a dedicated ORM class with your own custom properties (like TSQLUserPreferences), and use Ctxt.SessionUser as ID.
That is, TSQLUserPreferences.ID matches TSQLAuthUser.ID.

If you really want ot use TSQLMyAuthUser custom properties, then use the ORM methods to update its values. But they won't be modified in the current session User instance.

Offline

#7 2020-06-17 08:46:52

tomek
Member
Registered: 2017-10-24
Posts: 46

Re: Custom User/Session properties on server side

ab wrote:

If you really want ot use TSQLMyAuthUser custom properties, then use the ORM methods to update its values. But they won't be modified in the current session User instance.

Custom data for the user are supposed to be valid for current session only, won't be stored in db and may differ in next session. That's why TSQLAuthUser.Data seemed to be perfect for this purpose. Can you give an example of using TSQLAuthUser.Data?

Offline

#8 2020-06-17 09:21:57

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: Custom User/Session properties on server side

So you don't have to store it in the user instance, but in the session instance.

Try to define your own session class and assign it to TSQLRestServer.SessionClass.

Offline

#9 2020-06-18 08:34:18

tomek
Member
Registered: 2017-10-24
Posts: 46

Re: Custom User/Session properties on server side

Yes, it can be either in User or Session (as stated in post title smile ), TSQLAuthUser.Data was the first choice.
Own session class did the job, thx.

Offline

Board footer

Powered by FluxBB