React Native对接Inoreader OAuth2换取令牌时出现400 Bad Request错误
Hey there, let’s tackle this frustrating 400 Bad Request issue when exchanging your authorization code for an OAuth2 token with Inoreader in React Native. An undefined response text makes debugging way harder, but let’s break down the most likely fixes step by step:
1. Fix Your Request’s Content-Type & Parameter Encoding
OAuth2 token endpoints almost universally expect data in application/x-www-form-urlencoded format—not JSON. This is one of the most common slip-ups in React Native fetch calls:
- Set the correct header: Add
'Content-Type': 'application/x-www-form-urlencoded'to your request headers. - Encode parameters properly: Don’t pass a JSON object directly in the body. Convert your parameters to a URL-encoded string instead, using a library like
query-stringor manual stringification:
import queryString from 'query-string'; const tokenParams = { grant_type: 'authorization_code', code: 'YOUR_AUTHORIZATION_CODE', client_id: 'YOUR_CLIENT_ID', client_secret: 'YOUR_CLIENT_SECRET', redirect_uri: 'YOUR_REDIRECT_URI' }; fetch('https://www.inoreader.com/oauth2/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: queryString.stringify(tokenParams) })
2. Verify Client Credential Authentication
Inoreader requires client authentication via Basic Auth for token exchanges. That means you need to encode your client_id:client_secret string in Base64 and add it to the Authorization header:
const credentials = btoa(`${YOUR_CLIENT_ID}:${YOUR_CLIENT_SECRET}`); // Add this line to your request headers: 'Authorization': `Basic ${credentials}`
Double-check that your client ID and secret match exactly what’s listed in your Inoreader developer app settings—even a single typo here will trigger a 400 error.
3. Fix Response Parsing to Get Real Error Details
The "undefined" response text is probably because you’re trying to parse a non-JSON response as JSON. Modify your fetch handler to capture raw text when the request fails:
fetch(tokenUrl, { /* your request config */ }) .then(response => { if (!response.ok) { // First grab the raw error text to see what Inoreader is actually sending return response.text().then(errorText => { throw new Error(`HTTP Error ${response.status}: ${errorText || 'No error message provided'}`); }); } return response.json(); }) .catch(error => { console.error('Token exchange failed:', error.message); });
This will give you the actual error message from Inoreader, which is critical for spotting issues like invalid redirect URIs or expired authorization codes.
4. Double-Check All Parameter Values
Even tiny mismatches can break the flow:
redirect_uri: Must be identical to the one registered in your Inoreader app (including protocol, likemyapp://inoreader-callback—no trailing slashes unless you added them in the settings).grant_type: Must be exactlyauthorization_code(case-sensitive).- Authorization code: Ensure it hasn’t expired (most codes are valid for 10-15 minutes) and hasn’t been used before.
5. Rule Out React Native-Specific Quirks
- Network Permissions: For Android, make sure you’ve added the
INTERNETpermission inAndroidManifest.xml. - Simulator Network: If testing on a simulator, confirm it has unobstructed internet access (no proxy issues blocking requests to Inoreader’s API).
Once you implement these fixes, you’ll either get a valid token or a clear error message that points you to the remaining issue.
内容的提问来源于stack exchange,提问作者Keshav Moorthy

