Authentication
Authenticating as an application
An application can authenticate itself via the Client Credentials grant. In this mode, no user is involved and permissions (such as access to a campsite) must be granted directly to the application. This mode is most useful, if integration with Cynox IoT is managed transparently by the application itself and configuration is done manually by the application provider on behalf of the campsite owner.
To obtain the required Client ID and a Client Secret, please contact us.
Obtaining an access token
To obtain an access token using the Client Credentials grant, use the OAuth token endpoint at https://api.staging.iot.cynox.de/o/token/.
The client credentials (Client ID and Client Secret) must be passed via HTTP Basic Auth.
curl --request POST \ --url https://api.staging.iot.cynox.de/o/token/ \ --header 'Authorization: Basic YzEyMzpzMTIz' \ --data grant_type=client_credentials \ --data scope=devices:readimport requests
url = "https://api.staging.iot.cynox.de/o/token/"
payload = { "grant_type": "client_credentials", "scope": "devices:read"}headers = {"Authorization": "Basic YzEyMzpzMTIz"}
response = requests.post(url, data=payload, headers=headers)
print(response.json())<?php
$curl = curl_init();
curl_setopt_array($curl, [ CURLOPT_URL => "https://api.staging.iot.cynox.de/o/token/", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "grant_type=client_credentials&scope=devices%3Aread", CURLOPT_HTTPHEADER => [ "Authorization: Basic YzEyMzpzMTIz" ],]);
$response = curl_exec($curl);$err = curl_error($curl);
curl_close($curl);
if ($err) { echo "cURL Error #:" . $err;} else { echo $response;}const { URLSearchParams } = require('url');const fetch = require('node-fetch');
const encodedParams = new URLSearchParams();encodedParams.set('grant_type', 'client_credentials');encodedParams.set('scope', 'devices:read');
const url = 'https://api.staging.iot.cynox.de/o/token/';const options = { method: 'POST', headers: {Authorization: 'Basic YzEyMzpzMTIz'}, body: encodedParams};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}Use the resulting access token as a Bearer token with the Authorization header.
curl --request POST \ --url https://api.staging.iot.cynox.de/graphql/ \ --header 'Authorization: Bearer abc123456'import requests
url = "https://api.staging.iot.cynox.de/graphql/"
headers = {"Authorization": "Bearer abc123456"}
response = requests.post(url, headers=headers)
print(response.json())<?php
$curl = curl_init();
curl_setopt_array($curl, [ CURLOPT_URL => "https://api.staging.iot.cynox.de/graphql/", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_HTTPHEADER => [ "Authorization: Bearer abc123456" ],]);
$response = curl_exec($curl);$err = curl_error($curl);
curl_close($curl);
if ($err) { echo "cURL Error #:" . $err;} else { echo $response;}const fetch = require('node-fetch');
const url = 'https://api.staging.iot.cynox.de/graphql/';const options = {method: 'POST', headers: {Authorization: 'Bearer abc123456'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}Authentication on behalf of a user
To perform operations on behalf of a user, OAuth 2.0 with the Authorization Code with PKCE grant is used. Through this flow your application, if authorized by the user, will be able to obtain an access token and a refresh token.
This mode is most useful, if the integration with Cynox IoT is provided by the application as an Add-On functionality and the campsite owner initiates the connection between the application and Cynox IoT themselves. Typically this happens in the form of a button labelled “Connect with Cynox IoT” or similar with in the application. This button will initiate the connection by redirecting the user to the Cynox IoT login prompt. Once they have logged in, they will be asked to grant access to their account to the application. If successful, the application will receive a temporary code which can be exchanged for an access token and a refresh token.
To learn how to use the Authorization Code with PKCE flow, refer to this article.
To obtain the required Client ID and a Client Secret, please contact us.
Authorization URI
The Authorization URI is https://api.staging.iot.cynox.de/o/authorize/ with the
following query parameters:
response_type: Alwayscodecode_challenge: A hashed (SHA256) random code - see the above article for more detailscode_challenge_method: AlwaysS256(meaning SHA256)client_id: Your Application’s Client IDredirect_uri: Where you want the user to be redirected after logging instate: Optionally pass any necessary state here, this parameter will be passed as-is on to your application after the redirect. It is not parsed or used by Cynox IoT in any way other than to pass it through.
An example of a complete Authorization URI would be
https://api.staging.iot.cynox.de/o/authorize/?response_type=code&code_challenge=xxx&code_challenge_method=S256&client_id=c123&state=some_state_data&redirect_uri=https%3A%2F%2Fexample.com%2Foauth-redirect
After a successful authorization by the user, the user would then be redirected to
https://example.com/oauth-redirect?code=code123&state=some_state_data
At this point you can use the token endpoint https://api.staging.iot.cynox.de/o/token/ to exchange the code for a token pair.
Note that the following request must be done server-to-server, to prevent the client secret from being exposed.
This request will only succeed, if:
- the
redirect_urimatches the one configured for your application - The
code_verifieris set to the random code that was generated previously and sent in hashed form ascode_challenge - The
coderepresents a valid and not-expired verification code.
curl --request POST \ --url https://api.staging.iot.cynox.de/o/token/ \ --data client_id=c123 \ --data client_secret=s123 \ --data grant_type=authorization_code \ --data redirect_uri=https://example.com/oauth-redirect \ --data code_verifier=v123 \ --data code=code123import requests
url = "https://api.staging.iot.cynox.de/o/token/"
payload = { "client_id": "c123", "client_secret": "s123", "grant_type": "authorization_code", "redirect_uri": "https://example.com/oauth-redirect", "code_verifier": "v123", "code": "code123"}
response = requests.post(url, data=payload)
print(response.json())<?php
$curl = curl_init();
curl_setopt_array($curl, [ CURLOPT_URL => "https://api.staging.iot.cynox.de/o/token/", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "client_id=c123&client_secret=s123&grant_type=authorization_code&redirect_uri=https%3A%2F%2Fexample.com%2Foauth-redirect&code_verifier=v123&code=code123",]);
$response = curl_exec($curl);$err = curl_error($curl);
curl_close($curl);
if ($err) { echo "cURL Error #:" . $err;} else { echo $response;}const { URLSearchParams } = require('url');const fetch = require('node-fetch');
const encodedParams = new URLSearchParams();encodedParams.set('client_id', 'c123');encodedParams.set('client_secret', 's123');encodedParams.set('grant_type', 'authorization_code');encodedParams.set('redirect_uri', 'https://example.com/oauth-redirect');encodedParams.set('code_verifier', 'v123');encodedParams.set('code', 'code123');
const url = 'https://api.staging.iot.cynox.de/o/token/';const options = {method: 'POST', body: encodedParams};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}Refer to the above article to learn more about how to correctly implement the code challenge.