Skip to main content

Overview

The OpenEyes API uses HTTP Basic Authentication to secure endpoints. Authentication is implemented through the BasicAuthBehavior class attached to API controllers. Source: protected/modules/Api/behaviors/BasicAuthBehavior.php

Authentication Method

HTTP Basic Authentication

API requests must include valid OpenEyes user credentials in the HTTP Authorization header.
Authorization: Basic base64(username:password)

How It Works

The BasicAuthBehavior class (lines 17-42) implements the following flow:
  1. Extracts credentials from PHP_AUTH_USER and PHP_AUTH_PW server variables
  2. Creates a UserIdentity object with the provided credentials
  3. Authenticates against the OpenEyes user database
  4. Checks for the OprnApi access permission
  5. Returns 401 if authentication fails, 403 if permission is denied

Code Reference

public function beforeAction(\CEvent $action)
{
    $auth_user = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
    $auth_pwd = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';

    $identity = new UserIdentity($auth_user, $auth_pwd, null, null);
    if (!$identity->authenticate()) {
        $this->owner->renderJSON(401, '401 Unauthorized');
    }

    \Yii::app()->user->login($identity);

    if (!\Yii::app()->user->checkAccess('OprnApi')) {
        $this->owner->sendResponse(403, '403 Forbidden');
    }
}
Source: protected/modules/Api/behaviors/BasicAuthBehavior.php:26-41

Making Authenticated Requests

Using cURL

curl -X GET \
  https://your-openeyes-instance.com/api/v1/patient/search?term=Smith \
  -u username:password \
  -H "Content-Type: application/json"

Using JavaScript (Fetch API)

const username = 'api_user';
const password = 'secure_password';
const credentials = btoa(`${username}:${password}`);

fetch('https://your-openeyes-instance.com/api/v1/patient/search?term=Smith', {
  method: 'GET',
  headers: {
    'Authorization': `Basic ${credentials}`,
    'Content-Type': 'application/json'
  }
})
.then(response => response.json())
.then(data => console.log(data));

Using Python (requests)

import requests
from requests.auth import HTTPBasicAuth

url = 'https://your-openeyes-instance.com/api/v1/patient/search'
params = {'term': 'Smith'}

response = requests.get(
    url,
    params=params,
    auth=HTTPBasicAuth('username', 'password')
)

data = response.json()
print(data)

Using PHP (cURL)

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://your-openeyes-instance.com/api/v1/patient/search?term=Smith');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'username:password');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json'
));

$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);

Required Permissions

OprnApi Role

Users accessing the API must have the OprnApi role assigned. This is checked on every API request:
if (!\Yii::app()->user->checkAccess('OprnApi')) {
    $this->owner->sendResponse(403, '403 Forbidden');
}

Granting API Access

To grant API access to a user:
  1. Log in to OpenEyes as an administrator
  2. Navigate to Admin > Users
  3. Select the user account
  4. Assign the “OprnApi” role
  5. Save changes

Controller Integration

API controllers attach the BasicAuthBehavior in their behaviors() method:
public function behaviors()
{
    return array_merge(parent::behaviors(), [
        'BasicAuthBehavior' => ['class' => 'application.modules.Api.behaviors.BasicAuthBehavior'],
    ]);
}
Example from PatientController.php:35-40

Access Control Rules

In addition to authentication, controllers define access rules:
public function accessRules()
{
    return [
        [
            'allow',
            'actions' => ['search'],
            'users' => ['@'],  // @ means authenticated users
        ],
        [
            'deny',
            'users' => ['*'],  // deny all others
        ],
    ];
}
Source: PatientController.php:20-33

Authentication Errors

401 Unauthorized

Returned when:
  • Credentials are missing
  • Username or password is incorrect
  • User account is disabled
Response:
"401 Unauthorized"
Headers:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="OpenEyes"
Content-Type: application/json

403 Forbidden

Returned when:
  • Authentication succeeds but user lacks OprnApi permission
  • User account exists but doesn’t have API access
Response:
"403 Forbidden"
Headers:
HTTP/1.1 403 Forbidden
Content-Type: application/json

Security Considerations

Always use HTTPS in production to prevent credentials from being transmitted in plain text.

Best Practices

  1. Use HTTPS: Always use TLS/SSL encryption for API requests
  2. Dedicated API Users: Create separate user accounts specifically for API access
  3. Strong Passwords: Enforce strong password policies for API users
  4. Minimal Permissions: Grant only the OprnApi role, not additional administrative roles
  5. Credential Storage: Store credentials securely using environment variables or secret management
  6. Rotate Credentials: Periodically change API user passwords
  7. Monitor Access: Review API access logs regularly
  8. IP Restrictions: Consider restricting API access to known IP addresses at the firewall level

Example: Environment Variables

# .env file
OPENEYES_API_URL=https://your-openeyes-instance.com
OPENEYES_API_USER=api_integration_user
OPENEYES_API_PASS=secure_random_password
import os
from requests.auth import HTTPBasicAuth

api_url = os.getenv('OPENEYES_API_URL')
api_user = os.getenv('OPENEYES_API_USER')
api_pass = os.getenv('OPENEYES_API_PASS')

auth = HTTPBasicAuth(api_user, api_pass)

Testing Authentication

Test your credentials with a simple request:
curl -v -u username:password \
  https://your-openeyes-instance.com/api/v1/patient/search?term=test
Successful authentication will return status 200 with patient data. Failed authentication will return status 401 or 403.

Next Steps

Patient Search

Search for patients using authenticated requests

API Overview

Learn about API structure and conventions

Build docs developers (and LLMs) love