Token exchange

Log a user in on the device by scanning a QR code with the Things5 app.

These MQTT resources allow a device using the mqtt certificate to get a valid authentication token that can be used to interact with Things5 via API. This is achieved in combination with an already authenticated user.

The authenticated user will exchange his token for a new one that will be sent to the device via mqtt

The user must use Token exchange to authorize the session

TopicDirection
things5-production/v1/devices/{device_id}/req/token_exchange_session_reqDevice → Things5
things5-production/v1/devices/{device_id}/req/token_exchange_session_resThings5 → device
things5-production/v1/devices/{device_id}/req/token_exchange_resThings5 → device

Device → Things5: req/token_exchange_session_req

Create a new token exchange session in things5. A message will be sent via mqtt using the resource token exchange session response

things5-production/v1/devices/<device-id>/req/token_exchange_session_req

Payload

{
  "request_id": "87049f68-696f-4be8-a6cc-bf827c04ed0e",
  "type": "qr"
}

The request_id will be returned in the response. It can be used to match the request with the response. Should be random generated.

Payload Parameters

namedescriptionexample
request_idthe request id to be sent back by the device when sending the response
typehow the token exchange session data should be returned. qr returns qr code data and it's the only supported type so far.
things5_hostoptional. If provided the qr code response will contain a url build using things5_host instead of text data. Not supported for now

Things5 → device: req/token_exchange_session_res

After the session id has been created by things5 following a token exchange session request this message will be sent

things5-production/v1/devices/<device-id>/req/token_exchange_session_res

Payload

{
  "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=",
  "errors": [],
  "expiration_time": 1500000000030,
  "request_id": "87049f68-696f-4be8-a6cc-bf827c04ed0"
}

Payload Parameters

typedescriptionexample
datadata containing the session_id. if qr type was requested it's a base64 format string. Otherwise an encoded json
expiration_timeExpiration time of the session_id1500000000030
request_idThe request id sent in the authentication_qr_req87049f68-696f-4be8-a6cc-bf827c04ed0e
errorsarray of strings.
  • Ensure that the is valid and corresponds to a registered device.

Things5 → device: req/token_exchange_res

This topic is used by the cloud to send a access token and refresh token to the device after successful authentication of a different device.

things5-production/v1/devices/<device-id>/req/token_exchange_res

Payload

{
  "access_token": {access_token},
  "expires_in": 3600,
  "refresh_expires_in": 1800,
  "refresh_token": {refresh_token},
  "token_type": "Bearer",
  "id_token": {id_token},
  "not-before-policy": 0,
  "session_state": {UUID},
  "scope": "openid profile email"
}

The cloud will publish a message to this topic after the mobile device has successfully scanned the QR code and the session has been authenticated.

Payload Parameters

typedescriptionexample
access_tokenJWT token that the device will use for authenticating HTTPS requests.eyJhbGciOiASU-...
refresh_tokenJWT token that the device will use to keep the session active.eyJhbGciOiASU-...

Example response

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJWSk1CenoxVi1SSFN0SWwzbDJqcVd2WVl2NUZtbjJCSW5ySldwX2UzVzN3In0.eyJleHAiOjE3MDkyMzcyMjMsImlhdCI6MTcwOTIwMTMxNCwianRpIjoiYmUxMGUzMGYtODNlMC00NjY4LTgwYzAtZDRiYmNjOGM2OTA2IiwiaXNzIjoiaHR0cHM6Ly9rZXljbG9hay52aXN1cC5tZS9hdXRoL3JlYWxtcy90aGluZ3M1LXN0YWdpbmciLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiYTkzNTNhNjEtN2JjZS00MWYyLWE1MzctMGJmYjE1OTc4ZjU4IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYXBpIiwic2Vzc2lvbl9zdGF0ZSI6IjMwMjMzMGJhLTg0N2EtNGNmZC05NDllLTNkZjA5ZGUwOWVkNyIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRoaW5nczUtc3RhZ2luZyIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwic2lkIjoiMzAyMzMwYmEtODQ3YS00Y2ZkLTk0OWUtM2RmMDlkZTA5ZWQ3IiwiZW1haWxfdmVyaWZpZWQiOnRydWUsIm5hbWUiOiJBbmRyZWEgR3Jvc3NldHRpXHVEODNEXHVEQzEzIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYW5kcmVhQHZpc3VwLml0IiwiZ2l2ZW5fbmFtZSI6IkFuZHJlYSIsImZhbWlseV9uYW1lIjoiR3Jvc3NldHRpXHVEODNEXHVEQzEzIiwiZW1haWwiOiJhbmRyZWFAdmlzdXAuaXQifQ.MRLjWLW4Voi2N3n5y4CKAdw26gZDhBp0dW7cXrBSBbzVu6mLvW63Yg8ogiw7UMO3-B0afyrREo9SGeWJUryzE8BEKGAnuA_3kfZsaV_s6UrGuGX_Q-FCmNAdN1CBT8AvnbbryQlp0nfILaIHi4_ThGnsMq5I_JH6HStseePXPdZeEpuBW6R7mhs4eihI05rjAnUR8AxesHrHK1zjjqBloJdsdEWqinzvpQ8gtEtd116zpgtT6wNyzQh44FMiCQNfXoXDZuvuwpjHOdbF9QCvd_ZJ-Dg9zKZymBz-tY0J4KRP6BD_C9r3eXTv96PzgphcX_Jnf_FnBN53czUx5FE9HQ",
  "expires_in": 35909,
  "refresh_expires_in": 1800,
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI2N2NjZjRkMS1jOGZmLTQ2OTYtODk0Zi1hNzhjZGUxOTdiNjAifQ.eyJleHAiOjE3MDkyMDMxMTQsImlhdCI6MTcwOTIwMTMxNCwianRpIjoiM2Y5ZDBjNjgtZjUxNy00NjI0LTgyMzEtNjBmNDY2ZTZlNDRiIiwiaXNzIjoiaHR0cHM6Ly9rZXljbG9hay52aXN1cC5tZS9hdXRoL3JlYWxtcy90aGluZ3M1LXN0YWdpbmciLCJhdWQiOiJodHRwczovL2tleWNsb2FrLnZpc3VwLm1lL2F1dGgvcmVhbG1zL3RoaW5nczUtc3RhZ2luZyIsInN1YiI6ImE5MzUzYTYxLTdiY2UtNDFmMi1hNTM3LTBiZmIxNTk3OGY1OCIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJhcGkiLCJzZXNzaW9uX3N0YXRlIjoiMzAyMzMwYmEtODQ3YS00Y2ZkLTk0OWUtM2RmMDlkZTA5ZWQ3Iiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCIsInNpZCI6IjMwMjMzMGJhLTg0N2EtNGNmZC05NDllLTNkZjA5ZGUwOWVkNyJ9.bguGHmvt9xRcAiCWyDDziuGuM0Kft8q7OMD-U6fMSo8",
  "token_type": "Bearer",
  "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJWSk1CenoxVi1SSFN0SWwzbDJqcVd2WVl2NUZtbjJCSW5ySldwX2UzVzN3In0.eyJleHAiOjE3MDkyMzcyMjMsImlhdCI6MTcwOTIwMTMxNCwiYXV0aF90aW1lIjowLCJqdGkiOiJkY2RmMWI0NC1iZDkyLTQ4YjYtYTRjNS1jODA5OTg0YTk0MGQiLCJpc3MiOiJodHRwczovL2tleWNsb2FrLnZpc3VwLm1lL2F1dGgvcmVhbG1zL3RoaW5nczUtc3RhZ2luZyIsImF1ZCI6ImFwaSIsInN1YiI6ImE5MzUzYTYxLTdiY2UtNDFmMi1hNTM3LTBiZmIxNTk3OGY1OCIsInR5cCI6IklEIiwiYXpwIjoiYXBpIiwic2Vzc2lvbl9zdGF0ZSI6IjMwMjMzMGJhLTg0N2EtNGNmZC05NDllLTNkZjA5ZGUwOWVkNyIsImF0X2hhc2giOiJYYlQwODdiUXlla3JNQW8zX0owY3RBIiwic2lkIjoiMzAyMzMwYmEtODQ3YS00Y2ZkLTk0OWUtM2RmMDlkZTA5ZWQ3IiwiZW1haWxfdmVyaWZpZWQiOnRydWUsIm5hbWUiOiJBbmRyZWEgR3Jvc3NldHRpXHVEODNEXHVEQzEzIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYW5kcmVhQHZpc3VwLml0IiwiZ2l2ZW5fbmFtZSI6IkFuZHJlYSIsImZhbWlseV9uYW1lIjoiR3Jvc3NldHRpXHVEODNEXHVEQzEzIiwiZW1haWwiOiJhbmRyZWFAdmlzdXAuaXQifQ.NM1A9j5lNKN_jbJcpY2onumY4nARBHNbnAUI8A7WU-GvdRbUiquzLhfYDUDunH87DrEIfepqAROWN9ukcwBX9OD8bnttWr4LPrUbjtV8tfpMLBlvpY_OkvenY1hBLiOitDaKK5mvkdT1iuxS1Fv1EJinRaUYriTi1W0bp4Cx4EHCpiICjp8fQQnasiD_3y0Wq7Me9xIx0asnbtytIXbCZMrbIF750FE3EEGedm4y2vd2cB8OhObtlV5xnKJXJFhKYRsBZisfUuU-NDkx3yvR-BvS8ahHBo2d9grJLX2iU-4I_YH0frUMub8UssqF2qU34oxV2gfrrX9h_JCeIdqU2g",
  "not-before-policy": 0,
  "session_state": {UUID},
  "scope": "openid profile email"
}
  • The access_token should be included in the Authorization header of all future HTTP requests made by the device.
  • Ensure to handle token expiration, send your refresh_token to refresh token to keep your session active.