While watching the Wolfram Language in the Cloud presentation, the subject of authentication came up. While the Programming Cloud supposedly does support OAuth for APIs, that seems a little over-the-top if you're just accessing it from one app. While application auth tokens are coming in the future, I developed a simple solution and thought I'd share it.
I have this incredibly useful and worthwhile Instant API:
api = APIFunction[{"text" -> "String", "auth" -> "String"},
If[#auth == "MySuperSecretAndSecureAccessKey",
Return["You said: " <> #text], Return["Access denied!"]] &];
If I go to https://www.wolframcloud.com/objects/43fcc0c4-d4d1-4bc8-952b-e33360dc830b?text=Hi!&auth=MySuperSecretAndSecureAccessKey my text is echoed back to me. And if I use an incorrect key, it refuses to cooperate.
Foolproof, right?
Wrong.
If I eliminate the arguments from the URL, I get this error page:
And inside the JSON object-
-this traceback. Which is nice, except for the fact that it has my key.
So how do we fix this?
Many websites require username-password authentication. It is standard practice not to store the password in plaintext, but to calculate a hash and check logins against it.
I can get the hash of a string in the Wolfram Language with Hash[]
:
In[1]:= Hash["MySuperSecretAndSecureAccessKey"]
Out[1]= 5806601739209730667
I can modify my function to use that hash, like so:
api = APIFunction[{"text" -> "String", "auth" -> "String"},
If[Hash[#auth] == 5806601739209730667,
Return["You said: " <> #text], Return["Access denied!"]] &];
The API still works, and no modifications to the parameters are required. If I invoke the name error, all the recipient gets is my hash, which is almost completely useless.
Enjoy your newly secured Cloud API!