Disclosure Statement: This site contains affiliate links, which means that I may receive a commission if you make a purchase using these links. As an eBay Partner, I earn from qualifying purchases.

Authorization in google

igor666
Posts: 64
Joined: Fri Feb 08, 2019 1:25 pm

Re: Authorization in google

Post by igor666 »

Hello, I decided not to start a new topic, since the question is related to authorization in Google.
I looked through a lot of information, but I didn’t find anything other than using the ChromeRuntime mode (which, unfortunately, is not suitable) and changing the user agent. I tried to change the user agent using SetUserAgentOverride and directly through ExecuteDevToolsMethod, but there are cases when these functions did not work and the user agent remained unchanged. Are these functions asynchronous or not?
Somewhere I met that the ExecuteDevToolsMethod function should always be called on the UI thread, maybe this is the problem, I check the transition address in BeforeBrowse and if this is Google authorization, then I try to change the user agent. Please tell me how, in which handlers it is better to use the replacement of the user agent? Thank you.
User avatar
salvadordf
Posts: 4056
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: Authorization in google

Post by salvadordf »

Sadly, changing the user agent doesn't work for all accounts anymore.

It seems Google is blocking groups of accounts and the only known workaround is using the Chrome runtime mode.

If you want to make some more tests use the MobileBrowser demo. Some developers say that using a mobile user agent works sometimes and you can test that with the MobileBrowser demo.
igor666
Posts: 64
Joined: Fri Feb 08, 2019 1:25 pm

Re: Authorization in google

Post by igor666 »

This is what I understand. It is not clear how to determine in DevToolsMethodResult that this is exactly a user agent change, in order to then start loading the URL. Other methods also call this event too. I tried to use message_id to identify my call, but this parameter automatically increases by 1 with each call, so it is not possible to identify your call.
User avatar
salvadordf
Posts: 4056
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: Authorization in google

Post by salvadordf »

These are the code comments for that function :

Code: Select all

  ///
  /// Execute a function call over the DevTools protocol. This is a more
  /// structured version of SendDevToolsMessage. |message_id| is an incremental
  /// number that uniquely identifies the message (pass 0 to have the next
  /// number assigned automatically based on previous values). |function| is the
  /// function name. |params| are the function parameters, which may be NULL.
  /// See the DevTools protocol documentation (linked above) for details of
  /// supported functions and the expected |params| dictionary contents. This
  /// function will return the assigned message ID if called on the UI thread
  /// and the message was successfully submitted for validation, otherwise 0.
  /// See the SendDevToolsMessage documentation for additional usage
  /// information.
  ///
TChromiumCore.ExecuteDevToolsMethod will work if you call it from the main application thread but if you need to get the assigned message_id then you have to call it from the CEF UI thread.

The easiest way to do that is to call TChromiumCore.ExecuteDevToolsMethod from a TChromium event that is executed in the CEF UI thread but there are two more options :
  • Call TChromiumCore.ExecuteTaskOnCefThread and use the TChromiumCore.OnExecuteTaskOnCefThread event to call ExecuteDevToolsMethod. Read the code comments next to TChromiumCore.ExecuteTaskOnCefThread for more information.
  • Create a custom TCefTaskOwn class and call CefPostTask as you can see in TChromiumCore.ToggleAudioMuted, for example.
igor666
Posts: 64
Joined: Fri Feb 08, 2019 1:25 pm

Re: Authorization in google

Post by igor666 »

Thanks for the answer, but unfortunately both options were unsuccessful, anyway message_id in onDevToolsMethodResult increases by one with each new call.
Maybe I'm doing something wrong?
The first way is:

Code: Select all

procedure TfmMain.advChromiumExecuteTaskOnCefThread(Sender: TObject;
  aTaskID: Cardinal);
var
  TempParams: ICefDictionaryValue;
begin
  try
    TempParams := TCefDictionaryValueRef.New;
    TempParams.SetString('userAgent', 'My User-Agent');
    ChromiumComponent.ExecuteDevToolsMethod(10000, 'Emulation.setUserAgentOverride', TempParams);
  finally
    TempParams := nil;
  end;
end;
Second way:

Code: Select all

type
  TDevToolSetUserAgentTask = class(TCefTaskOwn)
    procedure Execute; override;
  end;
  
procedure TDevToolSetUserAgentTask.Execute;
var
  TempParams: ICefDictionaryValue;
begin
  inherited;
  try
    TempParams := TCefDictionaryValueRef.New;
    TempParams.SetString('userAgent', 'My User-Agent');
    ChromiumComponent.ExecuteDevToolsMethod(10000, 'Emulation.setUserAgentOverride', TempParams);
  finally
    TempParams := nil;
  end;
end;

in some my procedure do next

Task := TDevToolSetUserAgentTask.Create;
CefPostTask(TID_UI,Task);
In both cases, the first time it is called in the onDevToolsMethodResult event, the message_id is 10000, the second time it is 10001, and so on.
Student
Posts: 72
Joined: Tue Aug 07, 2018 9:20 am

Re: Authorization in google

Post by Student »

What you described does not contradict these comments

Code: Select all

///
  /// Execute a function call over the DevTools protocol. This is a more
  /// structured version of SendDevToolsMessage. |message_id| is an incremental
  /// number that uniquely identifies the message (pass 0 to have the next
  /// number assigned automatically based on previous values). |function| is the
  /// function name. |params| are the function parameters, which may be NULL.
  /// See the DevTools protocol documentation (linked above) for details of
  /// supported functions and the expected |params| dictionary contents. This
  /// function will return the assigned message ID if called on the UI thread
  /// and the message was successfully submitted for validation, otherwise 0.
  /// See the SendDevToolsMessage documentation for additional usage
  /// information.
  ///
Try using my code in the event BeforeResourceLoad, it's enough for me to get authorized through google mogle

Code: Select all

var Header, newHeader: ICefStringMultimap;

if (pos('https://accounts.google.com', request.url) = 1) then
  begin
    Header := TCefStringMultimapOwn.Create;
    newHeader := TCefStringMultimapOwn.Create;
    request.GetHeaderMap(Header);
    for i := 0 to Header.size - 1 do
    begin
      if Header.Key[i] = 'User-Agent' then
      begin
        newHeader.Append('User-Agent', 'Mozilla/5.0 (Windows NT ' + winver +
          '; Win64; x64; rv:' + verfirefox + ') Gecko/20100101 ' + randompwd(10)
          + '/' + verfirefox);
      end
      else
        newHeader.Append(Header.Key[i], Header.Value[i]);
    end;
    request.SetHeaderMap(newHeader);
    Header := nil;
    newHeader := nil;
  end;
igor666
Posts: 64
Joined: Fri Feb 08, 2019 1:25 pm

Re: Authorization in google

Post by igor666 »

What you described does not contradict these comments
Yes, indeed. I was hoping that only 0 does an automatic increase by one, and if you set a specific value, then I thought it would be received in the handler. It is a pity that it is impossible to identify what exactly we requested from ExecuteDevToolsMethod.
Try using my code in the event BeforeResourceLoad, it's enough for me to get authorized through google mogle
Thanks, I'll try, but this method has a big minus, the javascript will determine the real version of CEF. ExecuteDevToolsMethod will be more reliable in this regard.
User avatar
salvadordf
Posts: 4056
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: Authorization in google

Post by salvadordf »

You did nothing wrong. CEF works that way.

TChromium.ExecuteDevToolsMethod should return the real message_id value that was used to execute that method when you call it from the CEF UI thread.

Use that message_id value to handle the result.
thefunkyjoint
Posts: 460
Joined: Thu Aug 10, 2017 12:40 pm

Re: Authorization in google

Post by thefunkyjoint »

Regarding this issue, what i noticed is, usually when this 'browser not safe' happens, if you go back and really type the email and password (type manually, not copy and paste), usually on the second or third try it will work.
igor666
Posts: 64
Joined: Fri Feb 08, 2019 1:25 pm

Re: Authorization in google

Post by igor666 »

Regarding this issue, what i noticed is, usually when this 'browser not safe' happens, if you go back and really type the email and password (type manually, not copy and paste), usually on the second or third try it will work.
Not always, I would even say rarely and on certain UAs. And sometimes vice versa, if you return several times from entering the password, then on the second or third attempt a message about an unsafe browser will appear.

In general, I have already broken my head how to identify a specific call to ExecuteDevToolsMethod. Before loading the authorization page in Google, you need to cancel the download, change the UA and start the download. After exiting the authorization, it is necessary to return the UA, again before loading the page. Incremental message_id and asynchrony led me to a dead end. It can already try critical sections, open, fill variables with parameters and close it already in onDevToolsMethodResult after processing all parameters. But in this case, if for some reason onDevToolsMethodResult does not work, the program will not work.
Post Reply