Auth Token without expiration to use API


#1

Hi!

We are using the Data API Service to check if a device is online. For example, we use this call: http://docs.resin.io/runtime/data-api/#check-if-device-is-connected-to-vpn

We call this endpoint from our own system to monitor our devices.

But the problem we have is that we see that the Auth Token provided by Resin changes frequently. We would like to have an API key which doesn’t expire. Is this possible?

Thanks!
Flavia


#2

Briefly repeating my response from Intercom:

  • it’s possible to do: http://docs.resin.io/integrations/azure/#create-the-resin-io-api-key
  • currently the functionality is limited: you can only have the key with the same full permissions as the user who created it, and you cannot revoke the key at the moment
  • both of the abovementioned shortcomings will be addressed in the future
  • Once you have the key stop sending the Authorization header and instead start passing the key as ?apikey=API_KEY query param.

#3

Sorry, I had your answer also on the Resin chat so I forgot to answer. This is perfect, thanks!


#4

Hey,

Does that work too for PATCH/PUT/POST/DELETE requests?

Does it need to be in the URL ?apikey= or can it be in the body of the request?

Thanks.


#5

Hi! I was wondering the same! This API key can be used to modify application/devices/environement variables?

Thanks!
Flavia


#6

Hi

First, the answer is yes, you should add the same ?apikey= to the URL for non-GET requests, too.

Second, I have to mention that things have changed since the previous reply.
The keys produced by this endpoint now have the limited scope — they are only allowed to do the same operations the resin supervisor is doing from the device.
The API keys in their current form are deprecated for the user’s API usage.

So what is the alternative?

First thing, we plan to implement the proper API keys (with configurable permissions, revoking interface, etc.). We have the clear path to it, but no ETA yet.

Second, what should you do to make the API requests and don’t hit the Auth token expiration issue?
Right now the recommended way is:

  • use the Auth token, start with the one you can see in the dashboard. You may want to create the special collaborator account for this purpose
  • you need a constantly running service or a cron job
  • the job has to send the GET /whoami request (passing the existing token as an auth header), get the response (it’s in plain text) and replace the saved token
  • the rest of the requests should always use the most recently obtained token

I’m currently looking for an equivalent request using our SDK or CLI.


#7

So if you’re using our JS SDK you can just send this request
resin.request.send({ baseUrl: 'https://api.resin.io', url: '/ping' })

It will automatically refresh the token (when needed) and save it.

It doubles as the resin API availability check so reporting the errors from this request can be useful.


#8

It looks like there’s no currently an equivalent CLI command so I’ve created an issue to keep track of it: https://github.com/resin-io/resin-cli/issues/465


#9

Thanks Eugene :slight_smile:

We are not using any of the SDKs, we need to use the API directly, and the solution you propose is currently not an option for us.

Can you keep us posted about API keys in the roadmap and when you expect it to be implemented?

Thanks!
Flavia


#10

Sure Flavia, will keep you posted.

Just to make it clear:

  • if the API key is currently working for you (given the recent restrictions to the scope) you can keep using it,
  • the SDK or the CLI is just a convenience method, the auth token can be refreshed with a simple request to the /whoami API endpoint (but I understand keeping the regularly running process can be not a good match for your app architecture).

#11

Reading what Eugene said, I’m doing the following way (might help someone trying to refresh the tokens):

I have two services in nodejs app, one running every time the server starts, the other every 6 days.

The two are the same despite the way they trigger, and when they run they:

1 - get the last apiKey saved in the database;
2 - do “resin.auth.loginWithToken(apiKey)” to log in;
3 - do “resin.request.send({ baseUrl: ‘https://api.resin.io’, url: ‘/ping’ });” so it will refresh the token when needed and save it in memory (Am I right with this assumption, that it only saves it to memory?)
4 - do “resin.token.get()” which will result in a promise that when resolved, return the apiKey saved into memory on the last step.
5 - save that apiKey in database.

Not sure if it’s the best way, but there’s my 2 cents.

EDIT: After seven days, the strategy didn’t manage to refresh the api token. By the readings on the DB, I suspect that the resin.request.send part isn’t refreshing the api Token when it’s about to expire. What do you think, @Eugene?

EDIT2: Apparently, my assumptions of “saving to memory” were totally wrong. On both commands are performed requests to resin server, and they both outputs the same apiKey (maybe because it’s not time to refresh them?) I’m searching the repository to know how resin identifies if it’s time to renew the past keys, and, when it does, if I can grab the new key with resin.token.get(). In the first time posted, I was doing them in a imperative fashion. But now I corrected: the latter fires after the former, using Promise chains.


#23

Working on solving this problem also. I am using the Python SDK, and there is no way to get an updated token from there. I include the “Requests” Python library and use the who_am_i endpoint from the Web API. This gets me a new Key from my old key. Currently just saving to a file, but will make that file encrypted on GitHub.
`
#Open file containing resin key
#Read key to variable
endpoint1 = "https://api.resin.io/whoami"
headers = {“Authorization”:“Bearer %s” % self.token}
r = requests.get(endpoint1,headers=headers)
newtoken = r.text
#write newtoken back to file

`


#25

Hi,
At the moment you can generate a named user API key with a direct API call:

curl -X POST "https://api.resin.io/api-key/user/full" \
    -H "Authorization: Bearer <yourbearertoken>" \
    -H "Content-Type: application/json" \
    --data-binary '{"name":"testapikey"}'

This will return a user api key which can be used to authenticate with the javascript resin-sdk (v8) and execute requests:

var ResinSdk = require('resin-sdk');
var sdk = ResinSdk();
sdk.auth.loginWithToken(returnedapikey).then(function() {
	return sdk.models.application.getAll();
}).then(function(apps) {
	console.log(apps);
});

or be used as a bearer token in any other API request:

curl -X get "https://api.resin.io/v3/device" \
    -H "Authorization: Bearer <returnedapikey>"

PS: a respective sdk method to generate api keys is planned for one of the upcoming sdk releases.
PS2: the python resin-sdk doesn’t support this yet (see: https://github.com/resin-io/resin-sdk-python/issues/62)


#31

Hi,

We are happy to let you know that you can now create API keys that do not expire from the Dashboard.

These API keys are named tokens that can be created / revoked as needed, and they can be used for authentication in the resin.io API, CLI, and SDKs (Node.js Python)

For more information you can check the relevant section in our documents: https://docs.resin.io/learn/manage/account/#api-keys

Thanks!

Kostas