Authentication

GraphQL API authentication - login, token refresh, and authorization

Overview

The Service API uses user account authentication with JWT tokens. Each user is assigned to a role with specific permissions.

Authentication Flow

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#73F9C1','primaryTextColor':'#143633','primaryBorderColor':'#143633','lineColor':'#143633','secondaryColor':'#C7FDE6','tertiaryColor':'#F6FAFA','actorBkg':'#73F9C1','actorBorder':'#143633','noteBorderColor':'#FF8862','noteBkgColor':'#FFCFC0','signalColor':'#143633'}}}%%
sequenceDiagram
    note over Client,API: Login
    Client->>API: LoginMutation($email, $password, $organizationName)
    API-->>Client: accessToken, refreshToken
    note over Client,API: RefreshToken
    Client->>API: RefreshMutation($refreshToken)
    API-->>Client: accessToken, refreshToken
    note over Client,API: Logout
    Client->>API: LogoutMutation()
    API-->>Client: Session terminated

Login

Authenticate with email, password, and organization name to receive access and refresh tokens.

Login Mutation

mutation Login($email: String!, $organizationName: String!, $password: String!) {
  login(loginInput: {
    email: $email,
    organizationName: $organizationName,
    password: $password
  }) {
    accessToken
    expiresIn
    refreshExpiresIn
    refreshToken
    organizationId
  }
}

Example Variables

{
  "email": "demo@haltian.com",
  "organizationName": "demo",
  "password": "your-password"
}

Response

{
  "data": {
    "login": {
      "accessToken": "eyJhbGciO...",
      "expiresIn": 900,
      "refreshExpiresIn": 43200,
      "refreshToken": "eyJhbGc...",
      "organizationId": "2a749da0-5512-..."
    }
  }
}

Token Details

TokenValidityPurpose
accessToken15 minutesAuthorization header for API requests
refreshToken12 hoursObtain new access token without re-login

Using the Access Token

Include the access token in the Authorization header for all API requests:

Authorization: Bearer eyJhbGciO...

Example with cURL

curl -X POST https://haltian-iot-api.example.com/v1/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer eyJhbGciO..." \
  -d '{"query": "{ devices { id name } }"}'

Refresh Token

Before the access token expires, use the refresh token to obtain a new access token without requiring the user to log in again.

Refresh Token Mutation

mutation RefreshToken($organizationId: String!, $refreshToken: String!) {
  refreshToken(refreshTokenInput: {
    organizationId: $organizationId,
    refreshToken: $refreshToken
  }) {
    accessToken
    expiresIn
    refreshExpiresIn
    refreshToken
  }
}

Token Refresh Strategy

  1. Track token expiration time client-side
  2. Refresh the token before it expires (e.g., at 80% of validity)
  3. Store new tokens securely
  4. If refresh fails, redirect to login

Logout

Terminate the session and invalidate tokens:

mutation Logout {
  logout {
    success
  }
}

API Endpoint

The GraphQL endpoint URL depends on your Haltian IoT deployment:

https://haltian-iot-api.{haltian_iot_center_domain}/v1/graphql

Where {haltian_iot_center_domain} is the same domain used for Haltian IoT Studio login.

Introspection

The API schema is available via GraphQL introspection:

  • Requires authentication
  • Schema adapts to user’s role (Manager sees full API, Viewer sees limited queries)
  • Use Postman, Apollo CLI, or other GraphQL clients to explore

Security Best Practices

  1. Never expose tokens in client-side code or version control
  2. Use HTTPS for all API communications
  3. Implement token refresh to maintain sessions without storing passwords
  4. Handle token expiration gracefully with automatic refresh or re-authentication
  5. Logout explicitly when the user session ends

Next Steps

  • Queries - Query devices, measurements, and assets
  • Mutations - Modify configurations and data