JIMSMITH 0 Posted November 7 For some reason I have to authorize my application through google to send email again. During the process I check the box indicates read, compuse, send email. I encounter an error indicated in the image below. The firewall has been turned off on this computer. Does anyone know how to resolve this error? Share this post Link to post
Remy Lebeau 1392 Posted November 7 Why are you connecting to localhost? What exact steps are you doing to reach this error? What API are you using to access Google? Share this post Link to post
JIMSMITH 0 Posted November 7 (edited) 10 hours ago, Remy Lebeau said: Why are you connecting to localhost? What exact steps are you doing to reach this error? What API are you using to access Google? Not sure why I end up with local. The application is in dev/test mode. I get to a web page that says google has not verified this app. Thanks for your help Google uses localhost for OAuth2 authentication during development to simplify the process of testing and debugging. When you're developing an application, you can use localhost as the redirect URI to avoid the complexities of setting up a public server for testing purposes. This allows developers to run and test their applications locally without exposing their credentials and tokens to the internet. Edited November 8 by JIMSMITH Share this post Link to post
rvk 33 Posted November 8 8 hours ago, JIMSMITH said: Not sure why I end up with local. The application is in dev/test mode. I get to a web page that says google has not verified this app. Thanks for your help This error page seems to be a step further in the normal OAuth2 process. You accepted the non-verified app, accepted the terms and now you end up on localhost with the desired code for getting the access token in the url parameters. You need to catch that url with a small http server. After getting that code from the url you can go ahead with the process of getting the access and refresh token. 1 Share this post Link to post
JIMSMITH 0 Posted November 8 5 hours ago, rvk said: This error page seems to be a step further in the normal OAuth2 process. You accepted the non-verified app, accepted the terms and now you end up on localhost with the desired code for getting the access token in the url parameters. You need to catch that url with a small http server. After getting that code from the url you can go ahead with the process of getting the access and refresh token. Do I find a http server on the web and install it? I will be checking for solutions in the meanwhile. The core of the app that I am testing is from Geoffrey Smith's GmailAuthsmtp demo. This entire oauth2 process is new to me and a little unclear. I think it has an http server component internally. Not sure if I broke it an it no longer works. Share this post Link to post
rvk 33 Posted November 8 1 minute ago, JIMSMITH said: Do I find a http server on the web and install it? No no, because you want to catch that URL it's easiest to create your own listening thread. I have an example for OAuth2 in combination with Lazarus/FPC and Synpase. (You can also use Synapse on Delphi but you could also use Indy) https://github.com/rvk01/google-oauth2 Relevant snippet: This is a minimalistic http server which server a string saying your program now has access and you can close the window. type THTTPServerThread = class(TThread) private ListenerSocket: TTCPBlockSocket; ConnectionSocket: TTCPBlockSocket; public Authorize_token: string; procedure Execute; override; procedure CancelThread(Sender: TObject; var CanClose: boolean); end; procedure THTTPServerThread.CancelThread(Sender: TObject; var CanClose: boolean); begin Terminate; end; procedure THTTPServerThread.Execute; var S: string; method, uri, protocol: string; OutputDataString: string; SendDataString: string; begin Authorize_token := ''; FreeOnTerminate := False; ListenerSocket := TTCPBlockSocket.Create; ConnectionSocket := TTCPBlockSocket.Create; try ListenerSocket.CreateSocket; ListenerSocket.setLinger(True, 10); ListenerSocket.Bind('localhost', '1500'); ListenerSocket.Listen; while not terminated do begin Sleep(1000); // Application.ProcessMessages; if ListenerSocket.CanRead(1000) and not terminated then begin ConnectionSocket.Socket := ListenerSocket.Accept; // read request line S := string(ConnectionSocket.RecvString(1000)); method := fetch(S, ' '); uri := fetch(S, ' '); protocol := fetch(S, ' '); // read request headers repeat S := string(ConnectionSocket.RecvString(1000)); until S = ''; // /?code=4/fegArZQDUJqFdoCw-1DU16ohYsoA5116feRuCW0LiuQ // /?error=access_denied Authorize_token := ''; if Pos('code=', uri) > 0 then begin Authorize_token := Copy(uri, Pos('code=', uri) + 5); end; if Authorize_token = '' then begin SendDataString := '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' + ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' + CRLF + '<html><center><h1>Something went wrong.<br><br>Application does not have access.<br><br>You can close this page.</h1></center></html>' + CRLF; end else begin SendDataString := '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' + ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' + CRLF + '<html><center><h1>Application now has access.<br><br>You can close this page.</h1></center></html>' + CRLF; end; OutputDataString := 'HTTP/1.0 200' + CRLF; OutputDataString := OutputDataString + 'Content-type: Text/Html' + CRLF; OutputDataString := OutputDataString + 'Content-length: ' + IntToStr(Length(SendDataString)) + CRLF; OutputDataString := OutputDataString + 'Connection: close' + CRLF; OutputDataString := OutputDataString + 'Date: ' + Rfc822DateTime(now) + CRLF; OutputDataString := OutputDataString + 'Server: Synapse' + CRLF; OutputDataString := OutputDataString + '' + CRLF; ConnectionSocket.SendString(ansistring(OutputDataString)); ConnectionSocket.SendString(ansistring(SendDataString)); ConnectionSocket.CloseSocket; Terminate; end; end; finally ConnectionSocket.Free; ListenerSocket.Free; end; end; Share this post Link to post
rvk 33 Posted November 8 BTW. You can still use app-passwords with Google. So if you are only doing this for you own account, creating an app password is easiest. If you need to allow your users to use their own account, then you need OAuth2. Share this post Link to post
Remy Lebeau 1392 Posted November 8 4 hours ago, JIMSMITH said: Do I find a http server on the web and install it? I will be checking for solutions in the meanwhile. The core of the app that I am testing is from Geoffrey Smith's GmailAuthsmtp demo. Geoffrey's demo uses Indy's TIdSMTP component to send email with an OAuth2 token. Indy has a TIdHTTPServer component (or TIdSimpleServer if you don't need a full-blown HTTP server). Share this post Link to post
JIMSMITH 0 Posted November 8 13 minutes ago, Remy Lebeau said: Geoffrey's demo uses Indy's TIdSMTP component to send email with an OAuth2 token. Indy has a TIdHTTPServer component (or TIdSimpleServer if you don't need a full-blown HTTP server). Remy , The product has a datamodule with a idhttpserver on it. I might have broken this part of the implementation. This is new ground for me with additional complications beyond my daily scope and skill set. I am digging into it to figure this oauth 2.0 process out. All assistance/input has been greatly appreciated. I need one of you sharp gents on retainer. Share this post Link to post
JIMSMITH 0 Posted November 9 (edited) 6 hours ago, Remy Lebeau said: Geoffrey's demo uses Indy's TIdSMTP component to send email with an OAuth2 token. Indy has a TIdHTTPServer component (or TIdSimpleServer if you don't need a full-blown HTTP server). Here is the latest information. The referenced mail project does include a TidHTTPServer. The port was changed and it no longer worked. I have corrected this problem and it works. Truth is I did not know that Oauth 2.0 communication required all of these pieces. I wish there was a flow diagram. Thanks for all of your help education. Edited November 9 by JIMSMITH Share this post Link to post
rvk 33 Posted November 9 23 minutes ago, JIMSMITH said: I wish there was a flow diagram. Well... Type in Oauth 2.0 communication in Google (or similar search terms), then select Images... and there you go... Lots of flow diagrams Share this post Link to post
Remy Lebeau 1392 Posted November 9 1 hour ago, JIMSMITH said: Truth is I did not know that Oauth 2.0 communication required all of these pieces. I wish there was a flow diagram. All of the major OAuth providers - Google, Microsoft, etc - should have full documentation about their workflows. Share this post Link to post
emileverh 21 Posted November 9 4 hours ago, Remy Lebeau said: All of the major OAuth providers - Google, Microsoft, etc - should have full documentation about their workflows. Correct! But... it's not an easy part of software to write! Share this post Link to post