#1 2025-09-25 17:39:36

testgary
Member
Registered: 2025-02-06
Posts: 37

Authentication

Question 1:
When building a website with TMvcApplication, if the frontend uses JavaScript to obtain data from the backend, what approach is preferable? For example, backend user management (create/read/update/delete), article management (create/read/update/delete), etc.

Question 2:
Currently I am using the callback type TOnRestServerCallBack = procedure(Ctxt: TRestServerUriContext) of object; I’m not sure if this direction is correct, or if there are better options.

Question 3:
If my direction is fine, when the frontend calls the backend TOnRestServerCallBack method, I always need to use CurrentSession.CheckAndRetrieve to validate the data in CookieData to check whether the user is logged in and has the corresponding permissions (since some operations require certain permissions). Is there another approach, because I feel that validating in every method and writing the same code is not a good solution?

Question 4:
procedure TRestServer.Auth(Ctxt: TRestServerUriContext);
From what I’ve seen in TRestServerDB’s authentication methods, it seems different from the validation inside TMvcApplication. In other words, even if I set ServiceMethodRegister’s aByPassAuthentication to False, I can’t share the validation with TMvcApplication and must write validation separately, which is a bit troublesome. Is there another approach?

procedure TBlogApplication.Delete(Ctxt: TRestServerUriContext);
var
    CookieData: TCookieData;
begin
    if CurrentSession.CheckAndRetrieve(@CookieData, TypeInfo(TCookieData)) > 0 then  
    ...
end;  

// Here I enabled TRestServerDB’s validation
(aRestModel as TRestServerDB).ServiceMethodRegister('Delete', Delete, False, [mGET]);            

Offline

#2 2025-09-25 18:29:08

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 15,240
Website

Re: Authentication

1) TMvcApplication purpose is to generate HTML using templates.
You can trick it using POST and the /json suffix in the URI, but it is not the best way.
I would use an interface based service instead.

2) No question I guess

3) and 4) mixing TMvcApplication and TRestServer is not something natural and easy.
Just stick with interface based services.

Offline

#3 2025-09-26 05:58:16

testgary
Member
Registered: 2025-02-06
Posts: 37

Re: Authentication

ab wrote:

3) and 4) mixing TMvcApplication and TRestServer is not something natural and easy.
Just stick with interface based services.

How can TMvcApplication and TRestServer use the same authentication system? I'm a bit confused now. I don't know how the interface-based method can share authentication with TMvcApplication. It's impossible that I have to log in to the website and then log in to TRestServer again, right?

Offline

#4 2025-09-26 07:51:20

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 15,240
Website

Re: Authentication

You can use TMvcSessionWithCookies.Context in your service method.

Offline

#5 2025-09-26 10:58:28

flydev
Member
From: France
Registered: 2020-11-27
Posts: 133
Website

Re: Authentication

To avoid writing same code over each method, you could set a service on a TRestServer to handle backend logic and attach your MVC instance to it. Then inherit your interfaces with something like that (TAppService will have access to CurrentSession):

  
  TAppService = class(TInjectableObjectRest)
  protected
    function TryGetSessionCookie(out S: TCookieData): boolean;
    function GetLoggedAuthorID(Right: TOrmAuthorRight): TID;
    function HasRight(Right: TOrmAuthorRight): boolean;
  end;
  
  TAppServer = class(TRestServerDB)
    FMvcApp: IMvcApplication;
    FAppService: TAppService;
  end;

then create a instance with a resolver and rest:

FMvcApp := ...
FAppService := TAppService.CreateWithResolverAndRest(Self.ServiceContainer, nil, Self);

TryGetSessionCookie implementation could look something like:

function TAppService.TryGetSessionCookie(out S: TCookieData): boolean;
begin
  result := false;
  S := Default(TCookieData);
  result := TAppServer(Server).MvcApp.CurrentSession.CheckAndRetrieve(@S, TypeInfo(TCookieData)) > 0;
end;

Write a service to handle backend logic:

TServiceResult = (seSuccess, seNotFound, seMissingField, sePersistenceError);

IBackendService = interface(IInvokable)
  ['{A513EF1E-62B1-44A3-A2A0-7F3A6E6F19E4}']
  function NewArticle: TServiceResult;
  function UpdateArticle(aPage: TPage): TServiceResult;
  function DeleteArticle(aID: TID): TServiceResult;
  // ...
end;

// inherit from TAppService
BackendService = class(TAppService, IBackendService)
  // ...
end; 

then register the backend service as usual on the rest server:

Self.ServiceDefine(TBackendService , [IBackendService]);

The JS client can then log in, get cookie and make backend calls... You could also hook on the *Uri rest events to set a custom "gate" logic.

Hope you get the idea...

Offline

#6 2025-09-27 14:11:49

testgary
Member
Registered: 2025-02-06
Posts: 37

Re: Authentication

  TAppServer = class(TRestServerDB)
    // There is no "CurrentSession" method in the IMvcApplication.
    // FMvcApp: IMvcApplication;

    // I changed it to this.
    FMvcApplication: TMvcApplication; 
    FAppService: TAppService;
  end;

// In MvcApp, it will prompt that the "CurrentSession" identifier cannot be found.
// result := TAppServer(Server).MvcApp.CurrentSession.CheckAndRetrieve(@S, TypeInfo(TCookieData)) > 0;

// I changed it to this.
result := TAppServer(Server).FMvcApplication.CurrentSession.CheckAndRetrieve(@S, TypeInfo(TCookieData)) > 0;

1、First of all, thank you very much for your help. With your method, the code runs well!
2、By the way, did you accidentally write a few lines of code incorrectly? I’ve put them in the comments. I’m not sure if I’m saying this correctly, because my skills are limited, so I’m not certain.

Offline

#7 2025-09-27 18:40:59

flydev
Member
From: France
Registered: 2020-11-27
Posts: 133
Website

Re: Authentication

It was a sort of pseudo-code, MvcApp could have been a public property.  Glad you get it working, i suggest you to read mormot.core.mvc and mormot.rest.mvc to learn about what @ab said in previous post and to optimize your setup.

Offline

Board footer

Powered by FluxBB