From here I know how to build a a basic service connection.
And that's fine in simple authentication cases but how do I do this for OAuth services?
Even more specifically, how can I do this for Google Drive?
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityFrom here I know how to build a a basic service connection.
And that's fine in simple authentication cases but how do I do this for OAuth services?
Even more specifically, how can I do this for Google Drive?
See this for the main issue that made it take so long to get this up
If you just want the service connection you can get it like this:
PacletInstall["ServiceConnection_GoogleDrive",
"Site"->"http://www.wolframcloud.com/objects/b3m2a1.paclets/PacletServer"
]
So this turned out to be a bit of a bear to get the details right for, but not terribly complex once they're dealt with.
Mathematica's built-in OAuth package has some inline docs which are helpful, but there was a lot of trial an error too.
Mostly, we need to provide the following parameters in the "ClientInfo"
field (i.e. the one that lays-out how to implement the authentication):
"AuthorizeEndpoint"
Which is the endpoint from which we pass our auth code.
For google this is: "https://accounts.google.com/o/oauth2/v2/auth"
"AccessEndpoint"
The endpoint from which we get the auth token after obtaining an auth code.
For google this is: "https://www.googleapis.com/oauth2/v4/token"
"RedirectURI"
The standard OAuth redirect URI. I set this up like so (well I put in a helper function in my template package that implements this at run time):
HTTPHandling`StartWebServer[
URLDispatcher[{___~~"oauth2callback"~~___}:>
APIFunction[{code},<display_code>]
]
Note that this is maybe even easier to do by creating a ChannelObject
to redirect to -- alternatively we could do something more than just display our auth code with the APIFunction
too.
Then we need both
"ConsumerKey"
and
"ConsumerSecret"
I have an encoded keychain mechanism (implemented with Encode
) built into my standard suite of tools so I just save these here.
You get these by registering an application at https://console.developers.google.com. I made one called MathematicaLink, but, alas, I can't share the client secret (literally -- Google doesn't allow this). Also see the answer here for a quick rundown on how to get that.
The last thing one needs for OAuth2 is a scope. This seems not to be adequately handled by the standard dialog so I had to cook this in myself.
But first, we'll need the "AuthenticationDialog"
parameter:
(
OAuthClient`tokenOAuthDialog[
gooledriveauthorizationendpointurl@#,
"GoogleDrive",
googledrivedata["icon"]
] &)
We mostly just use the standard built-in token dialog, but notice the gooledriveauthorizationendpointurl
. The OAuth client seems to pass an incorrect "scope"
(it's blank). So that function will need to re-parse the passed URL and correct the scope. It's simple, but I generalized and so my block of code is more than I want to put there.
Then since we've passed all the requisite junk the OAuthSigning`
package will operate correctly (for those interested in just getting tokens via this method that's where you'll want to dig around. Check out OAuthSigning`Private`OAuthFlow
to see how to get an access token from all of this data).
So here's a quick auth example rundown.
First the basic auth dialog:
Before that opens, if I'm coming from a fresh restart, it asks me for my keychain password (because of how I set it up -- not implemented by the OAuth`
package), but otherwise just opens that. Follow the link, choose the appropriate Google account and approve:
When I do this it routes to the redirect URI started with StartWebServer
:
I copy that key in:
And the OAuth package takes care of the rest.
And then just checking that the access token is being handled correctly:
In[11]:= $gd["ListFiles"]["files", All, "id"] // Normal // First
Out[11]= "1CfpLOne3LRBHXPFRNtlzjujuq66qIzX47ezNdr_XPls"
I'll get this paclet up for public consumption after I provide access to more than just the files API and make sure uploads work (I remember from a previous implementation of a Google Drive connection that it was a bit hairy -- hopefully the ServiceConnect framework smooths that out).
PacletInstall["ServiceConnection_GoogleDrive", "Site"->"http://www.wolframcloud.com/objects/b3m2a1.paclets/PacletServer" ]
to run MMA codes placed in Google Drive. But after installation, I do not know what to do to run the codes in GoogleDrive. I receive the message: Paclet[ServiceConnection_GoogleDrive,1.0.2, <>]
. Can you guide me step by step what to do next? Thank you.
$\endgroup$
Sep 16, 2020 at 22:06