sga*_*a62 6 node.js instagram instagram-api
https://api.instagram.com/oauth/access_token从我们的后端向(此处的步骤 2)发出 post 请求会导致 400 Bad Request,而没有任何其他信息。
我们始终能够使用 cURL 请求并在 iOS 模拟器上使用 fetch 访问 API 来获得成功的响应,但节点请求失败。我们现在已经尝试了几个请求库,包括request、node-fetch和axios,它们都显示相同的响应状态和错误消息。
这是成功运行的 cURL(忽略敏感数据):
curl -X POST \
https://api.instagram.com/oauth/access_token \
-H 'Accept: */*' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Host: api.instagram.com' \
-H 'Postman-Token: ${myPostmanToken} ' \
-H 'User-Agent: PostmanRuntime/7.11.0' \
-H 'accept-encoding: gzip, deflate' \
-H 'cache-control: no-cache' \
-H 'content-length: 403' \
-H 'cookie: ig_did=${my_ig_did}; rur=FTW; csrftoken=${mycsrftoken}; mid=${mymid}' \
-b 'ig_did=${my_ig_did}; rur=FTW; csrftoken=${mycsrftoken}; mid=${mymid}' \
-d 'client_id=${myClientId}&client_secret=${mysecret}&code=${myCode}&grant_type=authorization_code&redirect_uri=${myRedirectUri}'
Run Code Online (Sandbox Code Playgroud)
以上返回预期
{"error_type": "OAuthException", "code": 400, "error_message": "This authorization code has been used"}(base)
Run Code Online (Sandbox Code Playgroud)
但是,当我们尝试使用节点后端发出请求时,它始终会失败并显示 400 Bad Request。
下面是我们尝试过的节点代码:
const url = 'https://api.instagram.com/oauth/access_token';
const body = {
client_id: myClientId,
client_secret: myClientSecret,
code: myCode,
grant_type: 'authorization_code',
redirect_uri: myRedirectUri,
};
const options = {
headers: { 'Content-Type': 'application/json' },
};
return axios.post(url, body, options).then(resp => {
console.log(resp);
});
Run Code Online (Sandbox Code Playgroud)
我们还尝试x-www-form-url-encoded根据this SO post使用:
const url = 'https://api.instagram.com/oauth/access_token';
const body = {
client_id: myClientId,
client_secret: myClientSecret,
code: myCode,
grant_type: 'authorization_code',
redirect_uri: myRedirectUri,
};
const options = {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
};
return axios.post(url, body, options).then(resp => {
console.log(resp);
});
Run Code Online (Sandbox Code Playgroud)
我们还尝试根据此 SO post对其进行编码:
const url = 'https://api.instagram.com/oauth/access_token';
const body = {
client_id: myClientId,
client_secret: myClientSecret,
code: myCode,
grant_type: 'authorization_code',
redirect_uri: myRedirectUri,
};
var formBody = [];
for (var property in body) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(body[property]);
formBody.push(encodedKey + '=' + encodedValue);
}
formBody = formBody.join('&');
const options = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
};
return axios.post(url, formBody, options).then(resp => {
console.log(resp);
});
Run Code Online (Sandbox Code Playgroud)
这是整个 axios 响应对象,其中包括请求数据和标头:
Error: Request failed with status code 400
at createError (/Users/sgarza62/ditto-app/api/node_modules/axios/lib/core/createError.js:16:15)
at settle (/Users/sgarza62/ditto-app/api/node_modules/axios/lib/core/settle.js:17:12)
at IncomingMessage.handleStreamEnd (/Users/sgarza62/ditto-app/api/node_modules/axios/lib/adapters/http.js:236:11)
at IncomingMessage.emit (events.js:322:22)
at IncomingMessage.EventEmitter.emit (domain.js:482:12)
at endReadableNT (_stream_readable.js:1187:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
config: {
url: 'https://api.instagram.com/oauth/access_token',
method: 'post',
data: 'client_id=601492960801083&client_secret=56c3508989f3aa0eff2939201280c616&code=AQAr0t6KazHaErfxOychsqVqW9nOlczw8o_PrAKuktDaC6xH25gSiqPV4Wi-OSwHfqvyUhD8gbXDB31iZqDnLG0lRTvNGhRooUTfG41tlJgoxHFZ9JVJPkk9eoQfJTFKQfXKwsDST92pJx7bkcp_GugVtbhan1s-X9EJOgBoTo1LTVusWCnlXXt2QkgRU6Ji3fNkj3con_BElakFVmeKu4sXCuMb9CodXyeH_bEvbQosIw&grant_type=authorization_code&redirect_uri=https%3A%2F%2Fwww.ditto-app.com%2Finstagram',
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'axios/0.19.2',
'Content-Length': 403
},
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus]
},
request: ClientRequest {
_events: [Object: null prototype] {
socket: [Function],
abort: [Function],
aborted: [Function],
error: [Function],
timeout: [Function],
prefinish: [Function: requestOnPrefinish]
},
_eventsCount: 6,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: 'api.instagram.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.instagram.com',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 390,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
connection: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: 'api.instagram.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.instagram.com',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 390,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
_header: 'POST /oauth/access_token HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Content-Type: application/x-www-form-urlencoded\r\n' +
'User-Agent: axios/0.19.2\r\n' +
'Content-Length: 403\r\n' +
'Host: api.instagram.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object],
requests: {},
sockets: [Object],
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'POST',
insecureHTTPParser: undefined,
path: '/oauth/access_token',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
readable: false,
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
socket: [TLSSocket],
connection: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 400,
statusMessage: 'Bad Request',
client: [TLSSocket],
_consuming: false,
_dumped: false,
req: [Circular],
responseUrl: 'https://api.instagram.com/oauth/access_token',
redirects: [],
[Symbol(kCapture)]: false
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
_redirectable: Writable {
_writableState: [WritableState],
writable: true,
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_options: [Object],
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 403,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest: [Circular],
_currentUrl: 'https://api.instagram.com/oauth/access_token',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'content-type': [Array],
'user-agent': [Array],
'content-length': [Array],
host: [Array]
}
},
response: {
status: 400,
statusText: 'Bad Request',
headers: {
'content-type': 'application/json; charset=utf-8',
'ig-set-password-encryption-web-key-id': '87',
'ig-set-password-encryption-web-pub-key': '8dd9aad29d9a614c338cff479f850d3ec57c525c33b3f702ab65e9e057fc087e',
'ig-set-password-encryption-web-key-version': '9',
vary: 'Accept-Language, Cookie',
'content-language': 'en',
date: 'Thu, 18 Jun 2020 22:22:38 GMT, Thu, 18 Jun 2020 22:22:38 GMT',
'strict-transport-security': 'max-age=31536000',
'cache-control': 'private, no-cache, no-store, must-revalidate',
pragma: 'no-cache',
expires: 'Sat, 01 Jan 2000 00:00:00 GMT',
'x-frame-options': 'SAMEORIGIN',
'content-security-policy': "report-uri https://www.instagram.com/security/csp_report/; default-src 'self' https://www.instagram.com; img-src https: data: blob:; font-src https: data:; media-src 'self' blob: https://www.instagram.com https://*.cdninstagram.com https://*.fbcdn.net; manifest-src 'self' https://www.instagram.com; script-src 'self' https://instagram.com https://www.instagram.com https://*.www.instagram.com https://*.cdninstagram.com wss://www.instagram.com https://*.facebook.com https://*.fbcdn.net https://*.facebook.net 'unsafe-inline' 'unsafe-eval' blob:; style-src 'self' https://*.www.instagram.com https://www.instagram.com 'unsafe-inline'; connect-src 'self' https://instagram.com https://www.instagram.com https://*.www.instagram.com https://graph.instagram.com https://*.graph.instagram.com https://*.cdninstagram.com https://api.instagram.com https://i.instagram.com wss://www.instagram.com wss://edge-chat.instagram.com https://*.facebook.com https://*.fbcdn.net https://*.facebook.net chrome-extension://boadgeojelhgndaghljhdicfkmllpafd blob:; worker-src 'self' blob: https://www.instagram.com; frame-src 'self' https://instagram.com https://www.instagram.com https://staticxx.facebook.com https://www.facebook.com https://web.facebook.com https://connect.facebook.net https://m.facebook.com; object-src 'none'; upgrade-insecure-requests",
'x-content-type-options': 'nosniff',
'x-xss-protection': '0',
'x-aed': '15',
'access-control-expose-headers': 'X-IG-Set-WWW-Claim',
'set-cookie': [Array],
'x-fb-trip-id': '1082456386',
connection: 'close',
'content-length': '101'
},
config: {
url: 'https://api.instagram.com/oauth/access_token',
method: 'post',
data: 'client_id=601492960801083&client_secret=56c3508989f3aa0eff2939201280c616&code=AQAr0t6KazHaErfxOychsqVqW9nOlczw8o_PrAKuktDaC6xH25gSiqPV4Wi-OSwHfqvyUhD8gbXDB31iZqDnLG0lRTvNGhRooUTfG41tlJgoxHFZ9JVJPkk9eoQfJTFKQfXKwsDST92pJx7bkcp_GugVtbhan1s-X9EJOgBoTo1LTVusWCnlXXt2QkgRU6Ji3fNkj3con_BElakFVmeKu4sXCuMb9CodXyeH_bEvbQosIw&grant_type=authorization_code&redirect_uri=https%3A%2F%2Fwww.ditto-app.com%2Finstagram',
headers: [Object],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus]
},
request: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 6,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [TLSSocket],
connection: [TLSSocket],
_header: 'POST /oauth/access_token HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Content-Type: application/x-www-form-urlencoded\r\n' +
'User-Agent: axios/0.19.2\r\n' +
'Content-Length: 403\r\n' +
'Host: api.instagram.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
method: 'POST',
insecureHTTPParser: undefined,
path: '/oauth/access_token',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
data: {
error_type: 'OAuthException',
code: 400,
error_message: 'This authorization code has expired'
}
},
isAxiosError: true,
toJSON: [Function]
}
Run Code Online (Sandbox Code Playgroud)
如果有任何见解,我将不胜感激!
一个迟来的答案,以防对任何人有用。尽管其他 HTTP 堆栈的方法类似,但这里有一些与 Axios 类似的工作代码。
public async sendAuthorizationCodeGrant(code: string, codeVerifier: string): Promise<any> {
const formData = new URLSearchParams();
formData.append('grant_type', 'authorization_code');
formData.append('client_id', this._clientConfiguration.clientId);
formData.append('client_secret', this._clientConfiguration.clientSecret);
formData.append('code', code);
formData.append('redirect_uri', this._clientConfiguration.redirectUri);
formData.append('code_verifier', codeVerifier);
return this._postGrantMessage(formData);
}
private async _postGrantMessage(formData: URLSearchParams): Promise<any> {
const options = {
url: this._apiConfiguration.tokenEndpoint,
method: 'POST',
data: formData,
headers: {
'content-type': 'application/x-www-form-urlencoded',
'accept': 'application/json',
},
};
const authServerResponse = await axios.request(options as AxiosRequestConfig);
return authServerResponse.data;
Run Code Online (Sandbox Code Playgroud)
更多详细信息请参阅我的此类。为了获得最佳生产力,还旨在能够使用代理工具跟踪 Node.js HTTP 请求,如我的这篇博文中所示,以便您可以验证代码是否在做正确的事情。
| 归档时间: |
|
| 查看次数: |
3183 次 |
| 最近记录: |