Skip to content

tRPC Authentication Header Logging

How BlueClerk logs authorization headers and handles iOS fallback for mobile auth

Overview

BlueClerk's tRPC server automatically logs the authorization header prefix from incoming requests to help diagnose authentication issues. The server also accepts Bearer tokens from the X-Auth-Token header as a fallback for iOS mobile clients, where the standard Authorization header is stripped by the platform's networking layer.

iOS Authorization Header Issue

The Problem

As of May 2026, iOS (likely iOS 26.4.x or NSURLSession behavior) strips the literal Authorization header name from HTTP requests on this app. This is not caused by BlueClerk code changes - the issue appeared suddenly across all iOS devices, likely due to an iOS networking quirk or App Store review requirement.

The Solution

Mobile clients now send the same Bearer JWT under two headers:

  • Authorization - Standard header for web and other platforms
  • X-Auth-Token - Fallback header for iOS

The tRPC server prefers Authorization when present, then falls back to X-Auth-Token if not found.

What Gets Logged

Authorization Header Prefix

When a tRPC request includes an authorization or x-auth-token header:

  • First 20 characters of the header value
  • Request context - Which tRPC procedure was called
  • Logged to console - Appears in Vercel runtime logs for debugging

Example Log Output

[tRPC context] Authorization header: Bearer eyJhbGciOiJI...

Why This Matters

Debugging Mobile Auth

When mobile users report login issues, check the logs to verify:

  • Is the Bearer token being sent?
  • Which header is being used (Authorization or X-Auth-Token)?
  • Does the token format look correct?

Verifying Fallback Behavior

If iOS devices can't authenticate:

  1. Check if Authorization header appears in logs
  2. If missing, check if X-Auth-Token appears instead
  3. Verify the token value starts with "Bearer "

How the Fallback Works

Server-Side Logic

const authHeader =
  opts.headers.get("authorization") ?? opts.headers.get("x-auth-token")

This ensures:

  • Web clients use Authorization (standard)
  • Android clients use Authorization (standard)
  • iOS clients use X-Auth-Token (fallback)
  • No breaking changes for existing platforms

Token Verification

Once the header is retrieved (from either source), the server:

  1. Checks if it starts with "Bearer "
  2. Extracts the JWT token
  3. Verifies signature using AUTH_SECRET
  4. Decodes user info (id, email, role, companyId, tokenVersion)
  5. Creates authenticated session

Timeline

  • May 22, 2026 - FCM commit (coincidental timing, not causal)
  • May 30, 2026 - iOS header stripping confirmed via duplicate-header diagnostic
  • May 30, 2026 - X-Auth-Token fallback deployed

Questions

Q: Why not just use X-Auth-Token for everyone? A: The Authorization header is the HTTP standard for bearer tokens. Using it ensures compatibility with proxies, CDNs, and other HTTP infrastructure. The fallback is iOS-specific.

Q: What if both headers are present? A: The server prefers Authorization first, then falls back to X-Auth-Token. This ensures standard behavior when possible.

Q: Will this break old mobile clients? A: No. Old clients using Authorization continue to work. The fallback is additive - it doesn't remove existing functionality.

Was this helpful?
Contact Support →