Authentication
The authentication API described in this section is that which is currently implemented and used by Sherpa.ai apps.
There are two possible registration methods, register and anonymous register). The first is the most common scenario, the one to choose if you want Sherpa.ai to manage the users and their passwords. On the other hand, if you have an existing user database and you don't want Sherpa.ai to manage the users, use the anonymous register), which only requires a unique ID for your users (no password required):
Register
POST /auth/register
Register a new user and get the access token.
curl -X POST "https://api.sherpa.ai/v2/auth/register" \
-H "accept: application/json" \
-H "Accept-Language: es-ES" \
-H "Time-Zone: Europe/Madrid" \
-H "content-type: application/json" \
-d "{
\"apiKey\": \"XXXX-SHERPA-DELIVERED-PUBLIC-APIKEY-XXXX\",
\"email\": \"demo@sherpa.ai\",
\"password\": \"chooseYourStrongPassword\",
\"name\": \"demo\",
\"device\": \"demo-device\"
}"
{
"token": "XXXX-SHERPA-TOKEN-XXXX",
"type": "basic",
"expires": :1858915823282,
"username": "demo"
}
Parameters
Field | Source | Mandatory | Type | Description |
---|---|---|---|---|
apiKey | Body | ✓ | String | Public API key provided by Sherpa.ai |
Body | ✓ | String | User email | |
password | Body | ✓ | String | plain/text password |
name | Body | String | User name | |
device | Body | String | Unique ID to identify the device |
Response
Code | Name |
---|---|
201 | Created |
400 | Bad Request |
401 | Unauthorized |
403 | Forbidden |
409 | Conflict |
500 | Internal Server Error |
Field | Type | Description |
---|---|---|
token | String | User access token |
type | String | Token type. Only "basic" in this version. |
expires | Long | Token expiration time in milliseconds since epoch |
username | String | Username set for registration |
Login
POST /auth/login
Get a user access token.
curl -X POST "https://api.sherpa.ai/v2/auth/login" \
-H "accept: application/json" \
-H "Accept-Language: es-ES" \
-H "Time-Zone: Europe/Madrid" \
-H "content-type: application/json" \
-d "{
\"apiKey\": \"XXXX-SHERPA-DELIVERED-PUBLIC-APIKEY-XXXX\",
\"email\": \"demo@sherpa.ai\",
\"password\": \"chooseYourStrongPassword\",
\"deviceId\": \"demo-device\",
\"lat\": 43.3017218,
\"lon\": -2.9735617
}"
{
"token": "XXXX-SHERPA-TOKEN-XXXX",
"type": "basic",
"expires": :1858915823282
}
Parameters
Field | Source | Mandatory | Type | Description |
---|---|---|---|---|
apiKey | Body | ✓ | String | Public API key provided by Sherpa.ai |
Body | ✓ | String | User email | |
password | Body | ✓ | String | plain/text password |
deviceId | Body | ✓ | String | Unique ID to identify the device |
Response
Code | Name |
---|---|
200 | OK |
400 | Bad Request |
401 | Unauthorized |
500 | Internal Server Error |
Field | Type | Description |
---|---|---|
token | String | User access token |
type | String | Token type. Only "basic" in this version |
expires | Long | Token expiration time in milliseconds |
Logout
POST /auth/logout
Ends user session and expires access token.
Headers
Request Header | Description |
---|---|
Authorization | An authentication type followed by an access token. ex: Basic 73dbb14a-50d9-4277-897e-6cb48258d258 See Authentication section. |
curl -X POST "https://api.sherpa.ai/v2/auth/logout" \
-H "Authorization: Basic XXXX-SHERPA-TOKEN-XXXX" \
-H "accept: application/json" \
-H "Accept-Language: es-ES" \
-H "Time-Zone: Europe/Madrid"
Response
Code | Name |
---|---|
204 | No Content |
400 | Bad Request |
401 | Unauthorized |
500 | Internal Server Error |
Anonymous Register/login
POST /auth/user
With the anonymous register/login endpoint, a password is not needed in order to get access and call the service. This method is useful for API integration with an application that manages its own users.
If a user enters an external ID that does not exist, a new, generic user will be registered and will get the access token at the same time. If a user enters an external ID that exists, that ID will be used to login. This endpoint is intended for B2B use, where the client does not require user-level information, but rather generic authentication.
The main difference with /auth/register is that, in this case, it is not necessary to assign a password to the new user.
Because there will be no password-based authentication, this register/login action will be secured with a Hash-based message authentication protocol,
or HMAC.
The client must send the HMAC signature, along with a set of special HTTP headers, when making the request to an API endpoint. This ensures that the API call is being made from the stated client and that the data has not been tampered with.
The HMAC must be constructed with some extra HTTP headers, in order for this data to be correctly processed:
- The
public apikey
provided by Sherpa.ai that identifies you to the API server - The
private apikey
corresponding to the previous public key - URL encoded string representation of any GET variable parameters
Every signature has a limited lifetime of 10 seconds. Therefore, it is important that you have your server time synchronized via NTP or another precise time source.
Headers
Request Header | Description |
---|---|
X-Sherpa-apikey | The public API key |
X-Sherpa-timestamp | The current UTC Unix timestamp in miliseconds |
X-Sherpa-nonce | A random string (UUID recommended) in form of a nonce, in order to guarantee that two requests made at the same time have different signatures |
X-Sherpa-hmac | base-64 enconded HMAC signature, computed fromBASE64(HMAC-SHA1(private-key, {GET request queryParams}:{timestamp}:{nonce})) |
Parameters
Field | Source | Mandatory | Type | Description |
---|---|---|---|---|
externalId | Body | ✓ | String | User identifier |
device | Body | String | User device | |
name | Body | String | User name (register only) |
Response
Code | Name | Description |
---|---|---|
200 | OK | Login success |
201 | Created | Register success |
400 | Bad Request | |
401 | Unauthorized | |
409 | Conflict | |
500 | Internal Server Error |
Field | Type | Description |
---|---|---|
token | String | User access token |
type | String | Token type. Only "basic" in this version. |
expires | Long | Token expiration time in milliseconds since epoch |
username | String | Username created during registration |
X-Sherpa-hmac Example
-
Input data
https://api.sherpa.ai/v2/auth/user
stripped to/v2/auth/user
-
Header parameters will be involved in the HMAC header itself:
- UTC unix timestamp in miliseconds as (X-Sherpa-timestamp)
- Nonce (X-Sherpa-nonce)
-
Given the following data:
- Resource URL:
/v2/auth/user
- Timestamp:
1543257277148
- Nonce:
10ba816b-7ae5-48b3-b6cc-a042658bf3c7
- All of the above fields should be joined together as follows:
/v2/auth/user:1543257277148:10ba816b-7ae5-48b3-b6cc-a042658bf3c7
- Resource URL:
Using HMAC-SHA1 implementation and this example private key 1679ebfb-636d-415a-a035-fe55629fd950
the result should be:
* output: DB4E6FC4E6998348EB79D9CB999E77ADCE8C2C3E
* base-64 encoded output: 205vxOaZg0jrednLmZ53rc6MLD4=
A full example of the registration request would be as follows:
// Pre-request Script in Postman
var moment = require('moment');
var timestamp = moment.utc().valueOf();
var nonce = "randomUUID";
var signatureRawData = "/v2/auth/user:" + timestamp + ":" + nonce;
var privateKey = "privateKey"; // Private key provided by Sherpa
var hash = CryptoJS.HmacSHA1(signatureRawData, privateKey);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
pm.globals.set("Sherpa-hmac", hashInBase64);
pm.globals.set("Sherpa-timestamp", timestamp);
pm.globals.set("Sherpa-nonce", nonce);
Request example:
curl -X POST "https://api.sherpa.ai/v2/auth/user" \
-H "accept: application/json" \
-H "Accept-Language: es-ES" \
-H "Time-Zone: Europe/Madrid" \
-H "X-Sherpa-apikey: XXXX-SHERPA-DELIVERED-PUBLIC-APIKEY-XXXX" \
-H "X-Sherpa-timestamp: 1548084514112" \
-H "X-Sherpa-nonce: XXXX-SHERPA-RAMDOM-UUID-XXXX" \
-H "X-Sherpa-hmac: xxxxyyyyyyy***signature******" \
-H "content-type: application/json" \
-d "{
\"externalId\": \"demo@sherpa.ai\",
\"name\": \"demo\"
}"
Response example:
{
"token": "XXXX-SHERPA-TOKEN-XXXX",
"type": "basic",
"expires": :1858915823282,
"username": "demo"
}
HTTP code 201 will be returned in the first call. If a second call is made, HTTP code 200 will be returned.