OAuth 2.0 in Shortcuts

OAuth 2.0

The following will give a rough overview of how to setup OAuth 2.0 with Shortcuts. There are basically three components to be setup which are detailed further under the relevant headings:

  • Foursquare - Registering your “app” with Foursquare to obtain a Client ID and a Client Secret.
  • Server - Configuring your own server to redirect from a web URL to the Shortcuts app.
  • Shortcut - Setup your Shortcut to perform the authentication.

Foursquare

You will first need to create an Application with Foursquare to get your Client ID and Client Secret. Detailed information is available on the Foursquare Developer Website, but in simple terms you need to:

  1. Setup a new application at https://foursquare.com/developers/apps.
  2. Enter your Application URL. This is where you will put your redirect file (Server Section below). For me this is https://swarm.frenchesco.com/
  3. Enter your Redirect URI. This is the URL of the redirect.php file below. For me this is https://swarm.frenchesco.com/redirect.php?shortcut=Bumblebee
  4. Select Disable pushes to this app for Push API Notifications.

Once you have created your app you will be given a Client ID and Client Secret which you can put in your Shortcut.

If you want further information about how the OAuth authentication works with Foursquare, refer to the Foursquare - Authentication Docs.

Server

The following file needs to be created on a server that supports PHP. Most servers support PHP by default or should have instructions for setting it up.

redirect.php

<?php
$shortcut = $_REQUEST['shortcut'] ?: 'OAuth%202.0';
$code = $_REQUEST['code'];

header('Location: ' . 'shortcuts://run-shortcut?name=' . rawurlencode($shortcut) . '&input=text&text=' . rawurlencode($code));
die();
?>

Explanation line-by-line:

  1. Line 1: Get the shortcut parameter from the URL (In my example my shortcut name is called Bumblebee). If there is no shortcut parameter provided default to the shortcut name OAuth 2.0.
  2. Line 2: Get the code parameter from the URL. This code is passed by Foursquare API when it has Authenticated you.
  3. Line 4: Set the Location header to the Shortcut’s URL scheme. This basically causes a redirect back to your Shortcut. In my example this would redirect to shortcuts://run-shortcut?name=Bumblebee&input=text&text={Code Returned From Foursquare API}
  4. Line 5: Stop anything else from happening.

This will be called by the Foursquare API when returning the OAuth 2.0 token. In my example the URL https://swarm.frenchesco.com/redirect.php?shortcut=Bumblebee is passed as the redirect_uri in the access request (See Shortcut section below)

Shortcut

Bumblebee.shortcut

Dictionary - Auth

  1. Get file from iCloud: Shortcuts/Swarm/foursquare-access-token.json
  2. Get Dictionary Value for access_token (Stored as {Access Token From File})
  3. If Count Items = 0
    1. Get Shortcut Input (Stored as {Code})
    2. If Count Characters = 0
      1. Authenticate
      2. Open Url - https://foursquare.com/oauth2/authenticate?client_id={Auth.Client ID}
    3. Otherwise
      1. Obtain Access Token
      2. Create Folder Shortcuts/Swarm
      3. Get Contents of URL - https://foursquare.com/oauth2/access_token?client_id={Auth.Client ID}&client_secret={Auth.Client Secret}&grant_type=authorization_code&redirect_uri={Redirect URI - https://swarm.frenchesco.com/redirect.php?shortcut={Config.Shortcut Name}}&code={Code}
      4. Save to Shortcuts/Swarm/foursquare-access-token.json (Overwrite if file exists)
      5. Get Dictionary Value for access_token
  4. Otherwise
    1. Get access token from file via Get Variable for {Access Token From File}
  5. End If
  6. … the rest of your shortcut

Conclusion

That’s the general gist of it. It will probably make more sense once I share my shortcut and you can see how it works.

9 Likes

I hope you don’t mind but this is fabulous and deserves its own topic!

2 Likes

Yes - That’s fine. I guess when I need to break out Sublime Text to write something it’s probably a bit too long for a reply. :sweat_smile:

1 Like

thanks for this. I made a version in nodeJS and deployed it on my Raspberry Pi. I’m now trying this with the reddit api.

2 Likes

Just wanted to note a typo that might help others that held me up.
In the PHP script, “shortcut://run” should be “shortcuts://run”.
This has been helpful as I attempt to make a Yahoo Fantasy sports shortcut connecting to Yahoo’s oauth.

1 Like

Thanks. Sorry about the typo. I originally was using workflow://run-workflow but updated it for Shortcuts to be more relevant going forward, but I should have tested it as I made that typo. I have updated the original post with the correct URL scheme for other people coming here.

1 Like

Is there any chance you can share the Shortcuts that you use with this? (Obviously without the client id or secret)

I’ve been playing around with some ideas and want to see how your shortcuts are actually put together :slight_smile:

1 Like

I didn’t get time to finish adding all the features I wanted to add, but I’ve posted the Shortcut here:

Great post. I managed to get this working for me :slight_smile: Although is there any way to use

“Content-Type: application/x-www-form-urlencoded” in IOS shortcuts?

I want to avoid showing the client_id and client_secret in clear.

Many thanks

I’m not too sure what you’re trying to achieve by using application/x-www-form-urlencoded. I don’t think it would offer any additional security. Your best option at this stage is probably to just store the Client ID and Client Secret in a file stored in iCloud and make sure that the API you are calling is using HTTPS.

If you’re only worried about people seeing your Client ID and Secret when you have the shortcut open then you could base 64 encode it and then base 64 decode it when you need to use it, but it wouldn’t provide any extra security.

Thanks Marc! I am using shortcuts with Oauth to integrate with Mailchimp allowing a user of the shortcut to get access with their username and password, authenticating with that rather than creating an api key, and I was able to set up the php server redirect, but I am stuck on making an “out of band” POST request in Curl with the auth code to then obtain the auth token. Any ideas about resources for whether this part (using MC rather than foursquare)

should be either server side (with which I have much less experience but may be necessary in order to include client secret) or as a RESTful request in shortcuts would be great. Thanks!

The mailchimp documentation (photo attached of specific part) https://developer.mailchimp.com/documentation/mailchimp/guides/how-to-use-oauth2/

You need to specify the url to your PHP file as the redirect_uri parameter. In Shortcuts you need to replicate that curl request with a Get Contents of URL action with method POST, and (I think) Request Body as Form and each of those parameters (grant_type, client_id, client_secret, redirect_uri, code) as fields.

After authenticating with Mailchimp, Mailchimp will redirect to your redirect_uri (Your PHP code) which in turn will translate that return URL to a url scheme to launch your shortcut again with the response as the shortcut input. Your shortcut will need to be able to process that shortcut input and store that response to iCloud for example so you don’t have to authenticate each time you run your shortcut. On subsequent runs of your Shortcut you read the response that you stored in iCloud first and only authenticate if you don’t have a response already stored.

Refer to my Bumblebee Shortcut as an example as it has a pretty similar authentication flow.

Hope that makes sense.

Did you ever get the Reddit API working with Shortcuts?

I did but it was too cumbersome to maintain and update. So, I’ve rebuilt it using the next best thing - Scriptable. You can check it out here.

And since Scriptable has shortcuts actions, you can use it with shortcuts.

1 Like

Thanks! Fortunately, I just discovered that I can do what I needed, which is scraping Reddit posts, with a much simpler method: adding /json to the end of a URL: https://www.reddit.com/r/shortcuts/comments/y86l7g/scraping_reddit/