Skip to main content

Authentication

Learn how to deal with Authentication.

Authentications is needed for all calls to GBFS API, this can be done by using the credentials provided.

How to select the correct flow?

Depending on the type of credentials provisioned, the steps for generating an signing the token are different.

The credentials type can be identified by simply looking at the domain of the email provided with the credentials:

  • External Organization: @external.organization.ridedott.com.
  • IAM (Deprecated): @identity.iam.ridedott.com or @com-ridedott-third-party.iam.gserviceaccount.com.

Select the tab that matches your credentials type!

comment: cspell:ignore pyjwt,ntte,utcnow,timedelta

Requirements

The GBFS API follows a custom variant of the

Oauth2 credentials grant

to facilitate authentication and authorization for our clients.

Consumers of the GBFS API should be able to generate and sign a valid JSON Web Token (JWT) using the provided credentials.

The JWT can be passed via an Authorization header in the request as a Bearer token:

Authorization: Bearer token

Generating and Signing a Valid JWT

This section intends to show how to use the provisioned API credentials for generating and signing the token.

info
  • Every request to the GBFS API must carry a newly generated token.

  • Every JWT has a minimum lifetime of 60 seconds and a maximum of 3600 seconds (1 hour). Furthermore, each token on the same key must have a timestamp that is later than any previously used token.
IMPORTANT

Please note that audience must be specified properly depending on which environment the request is going to be performed:

https://gbfs.api.staging.ridedott.com

info

The following examples are using "https://gbfs.api.staging.ridedott.com" as audience.

Here is an example of a generated JWT:

eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjYyMGY2OTRhLWJhZDktNGYxZS04ZjMwLTY3NWZkMTJkNjM2NCJ9.eyJpYXQiOjE2NTk2MjAyNzYsImV4cCI6MTY1OTYyMDI3NywiYXVkIjoiaHR0cHM6Ly9nYmZzLmFwaS5zdGFnaW5nLnJpZGVkb3R0LmNvbSIsImlzcyI6IlB1UktxMngyckNZa01YZG9JNFFuMHdtR3c4ajFAZXh0ZXJuYWwub3JnYW5pemF0aW9uLnJpZGVkb3R0LmNvbSIsImp0aSI6ImM2NzE1NDgyLWQzODQtNDJjNi05OTNhLWZmMmE5ZDRlMTdiYiJ9.7l0kRdMGbxwRN_TyOksa6j6Dc3fQHAYLcSe0euiXrRTrh77Btwp-5yKFCwQc4snMIwWAdW5lDRjQwP3S1B9xYw

Note that this is a deactivated token.

Node.js

Prerequisites:

  • Node.js
  • A package manager npm. All instructions in the documentation will follow the npm syntax.

Create an npm package:

npm init

Install the required dependencies:

npm install jsonwebtoken uuid uuidv4 --save

Create a new file bin/index.js within your node package


// This file lives in ./bin/index.js

const jwt = require('jsonwebtoken');
const fs = require('fs');
const { v4: uuidv4 } = require('uuid');

// The required EC private key that you were provided
const privateKey = fs.readFileSync('private.key');

// This can be empty for this example
const payload = {};

// Algorithm must be ES256
// For `kid` use the key you were provided
const header = {
alg: 'ES256',
kid: '{your-key-id}',
};

// Assemble the options
const options = {
header: header,
// Expiration timestamp MUST BE between 60 and 3600 seconds
expiresIn: 60,

// Use the identity ID to form the `issuer`
issuer: '{your-organization-id}@external.organization.ridedott.com',

// This remains constant regardless if you use gRPC or REST endpoints
audience: 'https://gbfs.api.staging.ridedott.com',

// Random UUID must be generated for each request
jwtid: uuidv4(),
};

const token = jwt.sign(payload, privateKey, options);

console.log(token);

Get the token by running the node script

node bin/index.js

Python

Prerequisites:

  • python3 installed
  • dependencies installed pip3 install pyjwt cryptography

import jwt
import uuid
import datetime

# Replace those with real values.

FAKE_KEY_ID = '73oPlD8nBlf7ts19JKJ0ntteZT55' FAKE_ORGANIZATION_ID =
'1CpBmkB67iDkXg9cwlIc' KEY_VALIDITY_SECONDS = 60

# Algorithm must be ES256

headers = { 'alg': 'ES256', 'kid': FAKE_KEY_ID, }

options = { 'exp': datetime.datetime.utcnow() +
datetime.timedelta(seconds=KEY_VALIDITY_SECONDS), 'iss':
f'{FAKE_ORGANIZATION_ID}@external.organization.ridedott.com', 'aud':
['https://gbfs.api.staging.ridedott.com'], # Random UUID must be generated for each request
'jti': str(uuid.uuid4()), }

# Read the private key from a file

with open('private.key', 'r') as key_file: private_key = key_file.read()

# Generate the JWT

token = jwt.encode(options, private_key, algorithm='ES256', headers=headers)

print(token)

Test the token

Run the following command to make a request to either staging or production environment:

curl --location --request GET \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {token-from-previous-step}' \
'https://gbfs.api.staging.ridedott.com/vehicles'