# Authentication with OAuth 2.0

The Cineamo API uses **OAuth 2.0** for authentication. All API requests require valid access tokens.

## 🎯 Supported Grant Types

Cineamo supports three OAuth 2.0 grant types:

1. **Authorization Code Grant with PKCE** - For user authentication (web/mobile apps)
2. **Client Credentials Grant** - For server-to-server authentication
3. **Refresh Token Grant** - For renewing expired access tokens

**Note**: Password Grant and Implicit Grant are **not supported** for security reasons.

---

## 🔐 Client Credentials Grant

Use this for **server-to-server** authentication (backend services, APIs, scripts).

### Request

```bash
POST https://api.cineamo.com/oauth/token
Content-Type: application/json

{
  "grant_type": "client_credentials",
  "client_id": "your_client_id",
  "client_secret": "your_client_secret",
  "scope": ""
}
```

### Response

```json
{
  "token_type": "Bearer",
  "expires_in": 86400,
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

**Key Points**:
- No `refresh_token` returned (not needed for client credentials)
- Access token expires in **24 hours** (86400 seconds)
- Request a new token after expiration

---

## 👤 Authorization Code Grant (PKCE)

Use this for **user authentication** (web apps, mobile apps, SPAs).

PKCE (Proof Key for Code Exchange) is **required** for security.

### Step 1: Generate PKCE Values

```javascript
// Generate code verifier (43-128 characters)
const codeVerifier = base64url(crypto.randomBytes(32));

// Generate code challenge (SHA-256 hash)
const codeChallenge = base64url(sha256(codeVerifier));
```

### Step 2: Authorization Request

```bash
GET https://api.cineamo.com/oauth/authorize?
  response_type=code&
  client_id=your_client_id&
  redirect_uri=https://yourapp.com/callback&
  scope=&
  state=random_state_string&
  code_challenge_method=S256&
  code_challenge=CODE_CHALLENGE_HERE
```

**Parameters**:
- `response_type`: Must be `code`
- `client_id`: Your OAuth client ID
- `redirect_uri`: Must match registered redirect URI
- `state`: Random string for CSRF protection
- `code_challenge_method`: Must be `S256` (SHA-256)
- `code_challenge`: Base64URL-encoded SHA-256 hash

### Step 3: User Authorization

User logs in and authorizes your application. On success, they're redirected to:

```
https://yourapp.com/callback?code=AUTHORIZATION_CODE&state=random_state_string
```

### Step 4: Token Exchange

```bash
POST https://api.cineamo.com/oauth/token
Content-Type: application/json

{
  "grant_type": "authorization_code",
  "client_id": "your_client_id",
  "client_secret": "your_client_secret",
  "redirect_uri": "https://yourapp.com/callback",
  "code": "AUTHORIZATION_CODE",
  "code_verifier": "CODE_VERIFIER_HERE"
}
```

### Response

```json
{
  "token_type": "Bearer",
  "expires_in": 86400,
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "def50200..."
}
```

**Key Points**:
- Access token expires in **24 hours**
- Refresh token expires in **2 years**
- Store refresh token securely for token renewal

---

## 🔄 Refresh Token Grant

Renew expired access tokens without re-authentication.

### Request

```bash
POST https://api.cineamo.com/oauth/token
Content-Type: application/json

{
  "grant_type": "refresh_token",
  "client_id": "your_client_id",
  "client_secret": "your_client_secret",
  "refresh_token": "def50200..."
}
```

### Response

```json
{
  "token_type": "Bearer",
  "expires_in": 86400,
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "def50200..."
}
```

**Key Points**:
- Returns **new** access token and **new** refresh token
- Old tokens are invalidated
- Refresh tokens expire after **2 years** of inactivity

---

## 🎯 Using Access Tokens

Include the access token in the `Authorization` header:

```bash
curl https://api.cineamo.com/cinemas \
  -H "Authorization: Bearer your_access_token"
```

---

## ⏰ Token Expiration

| Token Type | Expiration |
|------------|------------|
| Access Token | 24 hours (86400 seconds) |
| Refresh Token | 2 years |
| Authorization Code | 10 minutes |

**Best Practice**: Refresh tokens proactively before expiration (e.g., at 23 hours).

---

## 🔑 Obtaining Credentials

Contact your Cineamo account manager to receive:

- **Client ID** - Public identifier for your application
- **Client Secret** - Confidential secret (never expose publicly)
- **Redirect URI** - Authorized callback URL (for authorization code flow)

**Environments**:
- Production: `https://api.cineamo.com`
- Staging: `https://api.staging.cineamo.com`

---

## 🛡️ Security Best Practices

### DO ✅

- **Use HTTPS** for all requests (required)
- **Store secrets securely** (environment variables, secrets manager)
- **Use PKCE** for all authorization code flows
- **Validate `state` parameter** to prevent CSRF attacks
- **Rotate credentials** periodically
- **Monitor token usage** for anomalies

### DON'T ❌

- **Expose credentials** in client-side code or repositories
- **Share credentials** between different applications
- **Hardcode credentials** in source code
- **Reuse authorization codes** (single-use only)
- **Store tokens** in localStorage (use secure storage)

---

## 🚨 Error Responses

OAuth 2.0 errors follow this format:

```json
{
  "error": "invalid_client",
  "error_description": "Client authentication failed",
  "message": "Client authentication failed"
}
```

### Common Errors

| Error | Description | Solution |
|-------|-------------|----------|
| `invalid_client` | Invalid client credentials | Verify client_id and client_secret |
| `invalid_grant` | Invalid/expired authorization code or refresh token | Request new authorization |
| `unauthorized_client` | Client not authorized for this grant type | Contact Cineamo support |
| `invalid_request` | Missing required parameters | Check request format |
| `access_denied` | User denied authorization | User must approve access |

---

## 📋 Quick Reference

### Client Credentials Flow

```
POST /oauth/token
{
  "grant_type": "client_credentials",
  "client_id": "...",
  "client_secret": "..."
}
→ access_token (24h expiration)
```

### Authorization Code Flow

```
1. GET /oauth/authorize?code_challenge=...
   → Redirect to login
2. User authorizes
   → Redirect with code
3. POST /oauth/token with code + code_verifier
   → access_token + refresh_token
```

### Refresh Flow

```
POST /oauth/token
{
  "grant_type": "refresh_token",
  "refresh_token": "..."
}
→ new access_token + new refresh_token
```

---

## 📚 See Also

- [PHP Array Parameters](/php-arrays) - URL parameter syntax
- [HAL Responses](/hal-responses) - Response format
- [Fetching Showtimes](/showtimes) - Using authentication in practice
- [API Reference](/api) - Complete endpoint documentation

**OAuth 2.0 Spec**: [RFC 6749](https://tools.ietf.org/html/rfc6749)
**PKCE Spec**: [RFC 7636](https://tools.ietf.org/html/rfc7636)
