Access myCloudData without the login page

Using Delphi 10.4, Web Core...

I'm trying to access myCloudData without the user's first having to login.

In Connect to myCloudData without Login request Bruno indicated that:

You could as an alternative generate an access token once and always directly use the access token for accessing the service without going via OAUTH then anymore.

Which sounds like what I want.

I ran the "...web core demos Services\TMSWeb_myClouddata" project, and verified I could connect to a table in my account (this required an Auth login)

I then added a webedit and button - after succesfully connecting, I did:

WebEdit1.Text := WebmyCloudData1.AccessToken;

I then copied the access token to be used in the code.

I tried various versions of setting
WebmyCloudData1.AccessToken:= < long string >;

Unfortunately, the login screen always appears the first time run in a browser.

Looking at TRestClient.Connect, I see:

if FPersistTokens.Enabled then
  begin
    ReadTokens;

    if AccessToken <> '' then
    begin
      TestTokens;
    end
    else
      DoAuth;
  end
  else
    DoAuth;

So, I cheerfully did this:

  WebmyCloudData1.ClearTokens;
  WebmyCloudData1.PersistTokens.Enabled:=True;
  WebmyCloudData1.PersistTokens.Key:='myCloudData';
  WebmyCloudData1.AccessToken:= < long string >;
  WebmyCloudData1. (write tokens here)
  WebmyCloudData1.connect;

Unfortunately, WriteTokens is protected in WEBLib.Rest.pas, so I can't "pre-save" the access token just before calling it up.

Am I missing the blindingly obvious here? Is there an easier way of setting up the access token such that I don't need to present a login form to the users?

TIA

Cheers,
EdB

When PersistTokens.Enabled = true, the REST connection should persist the retrieved access token itself automatically.
I understand you do not want that this access token is first initially retrieved and automatically persisted but that you preset it (which is a security risk).
If you want to do this nevertheless, you could use the TLocalStorage class to write it yourself in local storage where the REST connection will retrieve it.

var
  ls: TLocalStorage;
begin
   ls := TLocalStorage.Create;
   ls.Values[PersistTokens.Key] := YourAccessToken;
   ls.Free;
end;

Thanks Bruno - that worked (after changing to ls.SetValue('myCloudData',MyAccessToken);

I'm setting up an employee COVID pre-screening tool.

Every morning employees get a text (using TAdvTwilio), they click on url and are taken to a simple questionnaire form (WebCore).

After clicking through all questions and a "I confirm that all is true" checkbox, the data is sent to the myCloudData table .

There will be a "table owner" who will have to log in properly, and a single added "share" user (using presaved token) with the minimum permissions to simply insert a new record.

All TMS, All Day...

Cheers,
EdB

Wow, sounds like an impressive use case!
If you have some time free, making a showcase of this would be very nice to publish on our website!

Sure - but I was actually thinking of handing all the details over to Holger to see if he wanted to put it in his next book...

I sort of have to finish it first though,.

EdB

Great!
Would be awesome!

@Holger_Flick

Great idea!

I've been working on this for almost two weeks.

I thought I had the "no login" (pre-set AccessToken) version working.

It looks like it doesn't work on iPhone at all, and apparently every Android device will need a different AccessToken - so, back to the drawing board.

I'm now probably just going to set up an XData web service on a box in a separate DMZ on my firewall.

Hmmm, shouldn't actually be that hard to set the web service to connect to myCloudData using a pre-defined AccessToken - so I still won't have to configure a full database server.

EdB

The access token is per device. Did you at least create and persist one first time the access token on each device?

I didn't realize it was "per device" when I started this two weeks ago.

Still, I learned a lot about the different ways to access myCloudData...

I could connect with iPhone when starting out with no saved tokens (log in page pops up).

I'd copy the token, but I couldn't find a way to store it and use it on the same device. That is, when I tried the same code that works on desktop and Android - iOS seems to ignore adding the token to LocalStorage to be recalled by WebMyCloudData..

IOW, while this worked on desktop and Android:

  WebmyCloudData1.App.Key := myKey;
  WebmyCloudData1.App.Secret := mySecret;
  WebmyCloudData1.App.CallbackURL := myCallBackURL;

  ls := TLocalStorage.create;
  ls.SetValue('myCloudData', myToken);   
  ls.free;

  WebmyCloudData1.PersistTokens.Enabled := true;
  WebmyCloudData1.PersistTokens.Key := 'myCloudData';

I couldn't get it to work on iOS (the one caveat here is I ran so many tests I may have used the wrong token).

Given that it's "per device" - a saved token isn't what I'm interested in anyway.

Unless there's a way to generate an AccessToken without the standard login page?

It is part of the security that you need to go via a myCloudData login, this is part of the OAuth2 specification.