Open simonw opened 2 years ago
I could switch to the flow for TVs and limited input devices... https://developers.google.com/identity/protocols/oauth2/limited-input-device#identify-access-scopes - but that doesn't appear to allow the scope that I need! It allows:
https://www.googleapis.com/auth/drive.appdata
https://www.googleapis.com/auth/drive.file
But I use: https://www.googleapis.com/auth/drive.readonly
I think what I need to do is fire up a localhost web server and redirect back to that.
The announcement is a little confusing here because it mentions that option being disabled too - but actually they are only disabling that for "iOS, Android and Chrome app OAuth client types".
I always worry about starting a local server for this kind of thing because I want my tools to be usable on a remote server via SSH, where running a web server doesn't make sense since you can't easily run a localhost browser there.
I may have to recommend people create the auth.json
file on their local machine with a browser and then scp
it to their server to capture that case.
I always worry about starting a local server for this kind of thing because I want my tools to be usable on a remote server via SSH, where running a web server doesn't make sense since you can't easily run a localhost browser there.
What rclone does is provide a special mode rclone authorize
to run locally to get the token only so users can but and paste that remotely.
I may have to recommend people create the
auth.json
file on their local machine with a browser and thenscp
it to their server to capture that case.
That is the other alternative which we call "copying the config" in the rclone world!
Here's a useful example of thehttp.server
mechanism from the Python standard library (I'd like not to add another dependency just to handle this): https://github.com/nltk/nltk/blob/develop/nltk/app/wordnet_app.py
Prototype:
diff --git a/google_drive_to_sqlite/cli.py b/google_drive_to_sqlite/cli.py
index 9fe0358..8010d24 100644
--- a/google_drive_to_sqlite/cli.py
+++ b/google_drive_to_sqlite/cli.py
@@ -1,5 +1,6 @@
from os import access
import click
+from http.server import BaseHTTPRequestHandler, HTTPServer
import httpx
import itertools
import json
@@ -123,6 +124,27 @@ def auth(auth, google_client_id, google_client_secret, scope):
google_client_secret = GOOGLE_CLIENT_SECRET
if scope is None:
scope = DEFAULT_SCOPE
+
+ class MyServerHandler(BaseHTTPRequestHandler):
+ def do_GET(self):
+ sp = self.path[1:]
+ print(sp)
+ self.send_response(200)
+ self.send_header("Content-type", "text/html; charset=utf-8")
+ self.end_headers()
+ self.wfile.write(
+ """
+ <h1>Hello world</h1>
+ """.encode(
+ "utf8"
+ )
+ )
+
+ server = HTTPServer(("127.0.0.1", 8182), MyServerHandler)
+ click.echo("http://127.0.0.1:8182")
+ server.serve_forever()
+ return
+
click.echo("Visit the following URL to authenticate with Google Drive")
click.echo("")
click.echo(start_auth_url(google_client_id, scope))
Need to configure things in the console next.
I run into your same issue within my project. Random stuff I'd love to share:
HTTPServer
with MyServerHandler
as you didself.path
contains both the requested path and the querystringqs = parse_qs(self.path[2:])
code
is found in qs
, use that for requesting access and refresh token.sys.exit(0)
when the flow is done
Just learned about this: https://developers.googleblog.com/2022/02/making-oauth-flows-safer.html?m=1#disallowed-oo
From a comment on Hacker News: https://news.ycombinator.com/item?id=30417735
I'm using that flow here: https://github.com/simonw/google-drive-to-sqlite/blob/1215097786c0ecdb12a766c9f2c8e53b2b0cd0f9/google_drive_to_sqlite/cli.py#L56-L65