How to store an authorization token?

For communication with the Remember The Milk API I need to store a (somewhat) persistent authorization token (the token is currently hard coded in my script, but I want to improve on that). I’m thinking of using FileManager to store the token (probably in iCloud if that means I have to authorize only once and can then use the token on all my iOS devices), but I’m not sure this is secure enough. Would using Credentials be safer? And how would one do that?

How do you store authorization tokens in your scripts?

You should use the Credentials option documented - it will make the key available to the scripts that need it, and is designed for this purpose :slight_smile:

How can I store the token? I see getValue, but no corresponding setValue.

Also, how does createWithUsernamePassword(identifier, description) work? I don’t see how to add the username and password. Is this signature correctly documented? Or is this a copy/paste mistake and are some parameters missing?

I’m 99% sure it’s saved when you call the authorize function :slight_smile:

The function your referencing sets up the storage space for the credential. You then assign the credential elements to it. Here are the first few lines from the example on the page Rosemary referenced that show just that.

var credential = Credential.create("My Service", "Description of the service to appear in user prompt.");

credential.addTextField("username", "Username");
credential.addPasswordField("password", "Password");

It would depend upon how a particular API works but upon calling authorize() some sort of authentication token must get captured by the credentials object must get captured. What I’m not clear on is if that is then implicitly bound to the credential until the API foces a refresh or if it is regenerated on each run using the username & password provided.

To me credentials just looks like a secured storage area; I’ve not done much with it yet. I would imagine that if you are using a secure key or token for a service then you would use addTextField() to capture it with an appropriate key name and include that in the header element / URL parameter for any API requests that require it.

How would Drafts be able to that without knowing the specifics of an API?

I also see Credentials as some kind of secure storage, but based on the documentation I thought it was for username & password only (or other things that a user has to enter manually). I don’t understand how to store other (not user facing) data, like an authorization token.

Does anyone have a working example?

This is an example (not mine) which uses Credentials with an API key: Todoist V3

1 Like

Thanks. I will try this.

In this example the user has to enter the token manually. I was hoping that I could store it from code, but now that I think of it I’m not even sure whether I can get the token in code from the API in the first place…

Probably not, I would suggest having the user enter their key.

Oh, there is an RTM API to get the token (rtm.auth.getToken) and the Pythonista script is using that…

(I hope I find some time for experimenting this weekend)

I’m afraid I still don’t understand the difference between these functions:

  • create
  • createWithUsernamePassword
  • createWithHostUsernamePassword

The Credentials documentation only gives an example for the first one.

Where can I find examples for the other two?

When you use create() you have to specify the fields to prompt the user for explicitly. The other two functions simply save you time & effort and automatically add the username/password/host fields (according to which function use). Just try them out.

Ah, only the fields?

I guess I’m focusing too much on the values.

Seems like it is (currently?) just not possible what I want: storing a value in Credential from code, without user intervention.

Then I have to use FileManager for now.

That is correct, it is not possible to set credentials programmatically. I’m not crazy about adding that as an option, but I’ll think about it. It could easily encourage some bad practices hard coding values.

1 Like

Unless I am missing something, _rob is looking for a way to share credentials across devices so they don’t need to be set up multiple times.

A better solution to that issue would be the ability to sync credentials rather than allowing credentials to be set up programmatically.

Is syncing possible?

I may be wrong, but I thought that the API he is using issues a limited time token from an initial authentication call and then he needs to use that is subsequent interactions. Just programmatic use rather than cross device use.

He does say that the token is ‘somewhat’ persistent, but looking at the RTM API documentation it looks like the token can be revoked, but isn’t time limited

I want the token to be persistent between multiple runs of my script (on the same device; if I can reuse the token on other devices that is a bonus).

The RTM API documentation is a bit vague about the lifetime of these tokens:

auth_token’s can and do expire (for example, if the user revokes the permissions they granted to your application).

Storing the token in Credentials will keep it for you.

I would also like Credentials to be sync’ed across devices