Skip to content

Debugging Checklist

When to Use

Use this guide when diagnosing csrf_token URL query argument is invalid or 403 errors in production. Use Common Pitfalls for known causes and fixes.

Decision

Symptom Check Tool
401 on any request OAuth token invalid or expired Step 1: curl against /jsonapi/user/user
Session endpoint returns no Set-Cookie Session not being created Step 2: curl with -v
Token is wrong length CSRF generation failed Step 3: wc -c on token
API call returns 403 Token invalid or wrong context Step 4: curl with cookie jar
Random failures Mixed session cookies Step 4 + clear SESS* cookies
Works with cookie jar, fails without Cookie not being sent by browser Browser DevTools — Application → Cookies

Pattern

Step 1: Verify OAuth works

curl -H "Authorization: Bearer $TOKEN" \
  https://your-drupal.com/jsonapi/user/user
# Expect: 200 with user data

Step 2: Verify session creation

curl -X POST -H "Authorization: Bearer $TOKEN" -v \
  https://your-drupal.com/api/deepchat/session
# Expect: 200, body = 43-char token, headers include Set-Cookie: SESS*

Step 3: Verify token format

echo "$TOKEN_VALUE" | wc -c  # Should be 44 (43 + newline)
echo "$TOKEN_VALUE" | grep -E '^[A-Za-z0-9_-]{43}$'  # Should match

Step 4: Test API with cookie jar

# 1. Get token, save cookie
curl -X POST -H "Authorization: Bearer $TOKEN" -c cookies.txt -v \
  https://your-drupal.com/api/deepchat/session

# 2. Use token with cookie
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{"assistant_id":"test","messages":[{"role":"user","text":"Hello"}]}' \
  "https://your-drupal.com/api/deepchat?token=$TOKEN_VALUE"

Step 5: Check Drupal logs

drush config:set system.logging error_level verbose -y && drush cr
drush watchdog:tail --extended
# Look for: "csrf_token URL query argument is invalid", session start messages

Step 6: Add Drupal debug logging

// In setSession() temporarily:
\Drupal::logger('ai_chatbot')->info('Session ID: @id, started: @s', [
  '@id' => $session->getId(),
  '@s'  => $session->isStarted() ? 'YES' : 'NO',
]);

Step 7: Add Next.js proxy logging

console.log('[DeepChat Proxy] access_token:', session?.accessToken?.substring(0, 10));
console.log('[DeepChat Proxy] CSRF token:', csrfToken?.substring(0, 10));
console.log('[DeepChat Proxy] Drupal status:', drupalResponse.status);
if (!drupalResponse.ok) console.error(await drupalResponse.text());

Common Mistakes

  • Wrong: Testing without -b cookies.txt and assuming cookie-less curl proves the issue → Right: Test both with and without cookie jar — difference isolates session persistence
  • Wrong: Comparing only against Drupal's native JS (deepchat-init.js) which uses cookie auth — Right: Native JS uses cookie auth (no session setup needed); OAuth flow requires explicit session creation

See Also