Getting ECONNREFUSED calling an external API with NextJS application using Auth0 - javascript

I have currently implemented Auth0 authentication on my NextJS app by following their docs, and am trying to call an external ExpressJS application by following their docs: https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md#access-an-external-api-from-an-api-route.
I have NextJS running on port 3000 and Express running on port 3001.
My express server is set up as follows:
const jwtCheck = expressjwt({
secret: jwksRsa.expressJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: process.env.AUTH0_JWKS_URI as string,
}) as GetVerificationKey,
audience: process.env.AUTH0_AUDIENCE as string,
issuer: process.env.AUTH0_ISSUER as string,
algorithms: ['RS256'],
})
app.use(jwtCheck)
When I try to make an unauthenticated request from my NextJS app to the external API, I get the UnauthorizedError: No authorization token was found error which ensures it is working. If I comment out app.use(jwtCheck) the requests are successful as there is no auth check.
I have my NextJS application set up as follows:
// [...auth0].ts
import { handleAuth, handleLogin } from '#auth0/nextjs-auth0'
export default handleAuth({
login: handleLogin({
authorizationParams: {
audience: process.env.AUTH0_AUDIENCE, // or AUTH0_AUDIENCE
// Add the `offline_access` scope to also get a Refresh Token
scope: 'openid profile email read:trips', // or AUTH0_SCOPE
},
}),
})
// /api/trips.ts
import { getAccessToken, withApiAuthRequired } from '#auth0/nextjs-auth0'
const apiURL = process.env.NEXT_PUBLIC_SERVER_URL
export default withApiAuthRequired(async function trips(req, res) {
// If your access token is expired and you have a refresh token
// `getAccessToken` will fetch you a new one using the `refresh_token` grant
const { accessToken } = await getAccessToken(req, res, {
scopes: ['read:trips'],
})
const response = await fetch(`${apiURL}/trips`, {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
Accept: 'application/json',
Authorization: `Bearer ${accessToken}`,
},
})
const trips = await response.json()
res.status(200).json(trips)
})
// /pages/trips/index.tsx
const TripsPage = (props: InferGetServerSidePropsType<typeof getServerSideProps>) => {
if (!props.user) return <div>User error!</div>
return (
<div>
// components that use the fetched data
</div>
)
}
export const getServerSideProps = withPageAuthRequired({
async getServerSideProps() {
const { data } = await axios.get('/api/trips')
try {
return {
props: {
data: data,
},
}
} catch (e) {
return {
notFound: true,
}
}
},
})
export default TripsPage
However, when I try to go to the http://localhost:3000/trips page after logging in, I get a error:
GET http://localhost:3000/trips 500 (Internal Server Error)
Uncaught Error: connect ECONNREFUSED ::1:80
at <unknown> (Error: connect ECONNREFUSED ::1:80)
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1487:16)
It seems like the request doesn't even leave my NextJS application. Seems like the internal API call failed. However, if I directly go to http://localhost:3000/api/trips I do get a response with the JSON data and if I console.log the accessToken it is valid. So authentication is working, but the issue is in the actual page which calls the NextJS proxy API, which calls my ExpressJS API.
The full error log on the NextJS console is:
error - AxiosError: connect ECONNREFUSED ::1:80
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1487:16) {
port: 80,
address: '::1',
syscall: 'connect',
code: 'ECONNREFUSED',
errno: -4078,
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [Function: httpAdapter],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: { FormData: [Function] },
validateStatus: [Function: validateStatus],
headers: {
Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.27.2'
},
method: 'get',
url: '/api/trips',
data: undefined
},
request: <ref *1> Writable {
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
afterWriteTickInfo: null,
buffered: [],
bufferedIndex: 0,
allBuffers: true,
allNoop: true,
pendingcb: 0,
constructed: true,
prefinished: false,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
errored: null,
closed: false,
closeEmitted: false,
[Symbol(kOnFinished)]: []
},
_events: [Object: null prototype] {
response: [Function: handleResponse],
error: [Function: handleRequestError],
socket: [Function: handleRequestSocket]
},
_eventsCount: 3,
_maxListeners: undefined,
_options: {
maxRedirects: 21,
maxBodyLength: 10485760,
protocol: 'http:',
path: '/api/trips',
method: 'GET',
headers: [Object],
agent: undefined,
agents: [Object],
auth: undefined,
hostname: null,
port: null,
nativeProtocols: [Object],
pathname: '/api/trips'
},
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: true,
socket: [Socket],
_header: 'GET /api/trips HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'User-Agent: axios/0.27.2\r\n' +
'Host: localhost\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: [Agent],
socketPath: undefined,
method: 'GET',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/api/trips',
_ended: false,
res: null,
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'localhost',
protocol: 'http:',
_redirectable: [Circular *1],
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kEndCalled)]: true,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype],
[Symbol(errored)]: null,
[Symbol(kUniqueHeaders)]: null
},
_currentUrl: 'http:/api/trips',
[Symbol(kCapture)]: false
},
page: '/trips'
}
Any idea what's going on here?

Try using 127.0.0.1 instead of localhost. I had the same issue.

The issue was that we not allowed to call an internal NextJS /api/ route in getServerSideProps. We need to call the external API directly, and not through the internal /api proxy.
More information: https://github.com/auth0/nextjs-auth0/issues/995

Related

NextJS not updating data from getStaticProps

I have a NextJS web app and NestJS backend. Locally with npm run dev or npm run build && npm start all works fine.
But deployed app (front and back in docker on different servers) not updating data on groups page.
When I build my app it generates a page with data from backend. Then I can add a new group (just new data), return to the group's page and can not see my mewGroup in the list.
My getStaticProps (not working):
export const getStaticProps: GetStaticProps<GroupProps> = async () => {
const { getGroups, getUsers, getModules } = useHttp();
const { data: groups } = await getGroups();
const { data: users } = await getUsers();
const { data: modules } = await getModules();
return {
props: { groups, users, modules },
revalidate: 5
};
};
My post request (working):
createGroup(body)
.then(() => {
push(routes.groups);
})
.catch((error) => {
throwError && throwError(error);
});
Again, it works fine locally even with the production backend.
But production web does not update any info, just can push some.
It's my first NextJS app, but I worked with react.
In my production logs I see the error, but have no idea how to handle it:
Error: getaddrinfo EAI_AGAIN {{MY_BACK_SERVER}}
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:71:26) {
errno: -3001,
code: 'EAI_AGAIN',
syscall: 'getaddrinfo',
hostname: '{{MY_BACK_SERVER}}',
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [Function: httpAdapter],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus],
headers: {
Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.24.0'
},
method: 'get',
url: 'http://{{MY_BACK_SERVER}}:5000/groups',
data: undefined
},
request: <ref *1> Writable {
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
afterWriteTickInfo: null,
buffered: [],
bufferedIndex: 0,
allBuffers: true,
allNoop: true,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
errored: null,
closed: false
},
_events: [Object: null prototype] {
response: [Function: handleResponse],
error: [Function: handleRequestError]
},
_eventsCount: 2,
_maxListeners: undefined,
_options: {
maxRedirects: 21,
maxBodyLength: 10485760,
protocol: 'http:',
path: '/groups',
method: 'GET',
headers: [Object],
agent: undefined,
agents: [Object],
auth: undefined,
hostname: '{{MY_BACK_SERVER}}',
port: '5000',
nativeProtocols: [Object],
pathname: '/groups'
},
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Socket],
_header: 'GET /groups HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'User-Agent: axios/0.24.0\r\n' +
'Host: {{MY_BACK_SERVER}}:5000\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
method: 'GET',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/groups',
_ended: false,
res: null,
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: '{{MY_BACK_SERVER}}',
protocol: 'http:',
_redirectable: [Circular *1],
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
_currentUrl: 'http://{{MY_BACK_SERVER}}:5000/groups',
[Symbol(kCapture)]: false
},
response: undefined,
isAxiosError: true,
toJSON: [Function: toJSON]
}
so when you first open the group page it showed you the information from the static file,
there are two cases -
now if there is a modification in the data (ie befor opening the group page for the first time) it will show you the old data (as it works with stale
while revalidate cache) and update the data (in background) for group page
(getStaticProps ). so when you again visit the group page again it
will show you the updated data.
Now the second case is (the one related to you) you opened the group page it checks there is no need to update the page in the
background as there is no new data in the server, it shows you the
data and then you in the same session updated the group info (added a
new data), next js will not show those newly created data because from
here it is serving you pages from the local cache. just because it
doesn't see any update of data in the first render.
You will have to do a full refresh to see the newly created data.
recommendation - use full page refresh occasionally (programmatically) when you think there may be a new data created or user server side rendering.
Thanks
Finally, I solve the problem. My container has no internet connection, SSR just can't ping the backend. POST request works well because it client-side request.

Axios/Nuxt "Certificate has expired" only when directly opening page, but not for a link from another page

I have a website I am helping to maintain (but did not build myself), using Nuxt.js and Axios. It is currently showing an odd server behavior on the Home page. If I directly visit the home page (say: https://example.org):
Browser: Server error (500)
Server: Certificate has expired (for the twitter feed data call)
This error also happens when I am on example.org/about (which works) and hit a link formed like: Home
However, if I visit the home page (both show link as https://example.org) via a link on say example.org/about which is formed like: <span>Home</span>:
Browser: Page works!
Server: No errors
So, oddly enough, even for two different links for '/' one leads to the error but the other does not (and they both display the same thing in the URL bar). If I open the link directly at example.org:5000/tweets then it works fine (footnote: not sure why the design choice was made to use a different port there, possibly related). Has anyone seen this kind of behavior and know why that might happen? It persists on safe mode and on all major browsers. No changes were made with the code from when it worked to when it stopped working in the last couple of days. The specific error that I receive is shown like the below.
{ Error: certificate has expired
at TLSSocket.<anonymous> (_tls_wrap.js:1105:38)
at emitNone (events.js:106:13)
at TLSSocket.emit (events.js:208:7)
at TLSSocket._finishInit (_tls_wrap.js:639:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38)
code: 'CERT_HAS_EXPIRED',
config:
{ adapter: [Function: httpAdapter],
transformRequest: { '0': [Function: transformRequest] },
transformResponse: { '0': [Function: transformResponse] },
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
headers:
{ Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.16.2' },
baseURL: 'https://example.org:5000/',
method: 'get',
url: 'https://example.org:5000/tweets',
data: undefined },
request:
Writable {
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object] },
writable: true,
domain: null,
_events:
{ response: [Function: handleResponse],
error: [Function: handleRequestError] },
_eventsCount: 2,
_maxListeners: undefined,
_options:
{ protocol: 'https:',
maxRedirects: 21,
maxBodyLength: 10485760,
hostname: 'example.org',
port: '5000',
path: '/tweets',
method: 'get',
headers: [Object],
agent: undefined,
auth: undefined,
nativeProtocols: [Object],
pathname: '/tweets' },
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest:
ClientRequest {
domain: null,
_events: [Object],
_eventsCount: 6,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
upgrading: false,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Object],
connection: [Object],
_header: 'GET /tweets HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nUser-Agent: axios/0.16.2\r\nHost: example.org:5000\r\nConnection: close\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Object],
socketPath: undefined,
timeout: undefined,
method: 'GET',
path: '/tweets',
_ended: false,
res: null,
aborted: undefined,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable: [Circular],
[Symbol(outHeadersKey)]: [Object] },
_currentUrl: 'https://example.org:5000/tweets' },
response: undefined,
statusCode: 500,
name: 'NuxtServerError' }
Upgrading to the latest version of Node resolved this issue for me. I was experiencing an identical issue to what you described on Node v8.10.0. I upgraded to Node v14.18.1 and restarted Nuxt, and now the site works normally.
sudo npm cache clean -f
sudo npm install -g n
sudo n stable

Is there a way I can call an API from an api in express the parameter value in axios is undefined how do i add parameters in axios from a variable

**I tried passing in a parameter to my route and then passing that parameter to the variable axios with the url. The request succeeds if I remove the params object and instead hardcode the parameter in the url.
I am trying to post the question, but my word is little and the code is too much. I don't know how I can solve this so the explanation is enough to solve the question. I have explained it to the best of my ability. the code can tell much for itself. Thank you.
const axios = require("axios");
dotenv.config();
const Url = "https://api.dhl.com/location-finder/v1/find-by-address";
exports.getLocation = (req, res, next) => {
const country = req.body.countryCode;
axios
.get(Url, {
params: {
countryCode: country}
,headers: {'DHL-API-Key': process.env.LOCATOR_API_KEY}})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
};```
//CODE CONSOLE LOG
**THIS IS THE CONSOLE LOG THE PARAMETER PART IS UNDEFINED HOW WILL I ADD THE PARAMETER
Error: Request failed with status code 400
at createError (/media/ALWI/HACKERFOREVER/MyProjects/JULEYBIB_SHIPPING/server/node_modules/axios/lib/core/createError.js:16:15)
at settle (/media/ALWI/HACKERFOREVER/MyProjects/JULEYBIB_SHIPPING/server/node_modules/axios/lib/core/settle.js:17:12)
at IncomingMessage.handleStreamEnd (/media/ALWI/HACKERFOREVER/MyProjects/JULEYBIB_SHIPPING/server/node_modules/axios/lib/adapters/http.js:236:11)
at IncomingMessage.emit (events.js:322:22)
at endReadableNT (_stream_readable.js:1187:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
config: {
url: 'https://api.dhl.com/location-finder/v1/find-by-address',
method: 'get',
params: { countryCode: undefined },
headers: {
Accept: 'application/json, text/plain, */*',
'DHL-API-Key': '**********************',
'User-Agent': 'axios/0.19.2'
},
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
data: undefined
},
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: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: 'api.dhl.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.dhl.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)]: 301,
[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.dhl.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.dhl.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)]: 301,
[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: 'GET /location-finder/v1/find-by-address HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'DHL-API-Key: *********************\r\n' +
'User-Agent: axios/0.19.2\r\n' +
'Host: api.dhl.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: 'GET',
insecureHTTPParser: undefined,
path: '/location-finder/v1/find-by-address',
_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.dhl.com/location-finder/v1/find-by-address',
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: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest: [Circular],
_currentUrl: 'https://api.dhl.com/location-finder/v1/find-by-address',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'dhl-api-key': [Array],
'user-agent': [Array],
host: [Array]
}
},
response: {**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
status: 400,
statusText: 'Bad Request',
headers: {
date: 'Mon, 04 May 2020 09:02:52 GMT',
'content-type': 'application/json',
'content-length': '71',
connection: 'close',
'access-control-allow-origin': '*',
'access-control-allow-headers': 'origin,x-requested-with,accept,accept-encoding,content-type,dhl-api-key',
'access-control-max-age': '3628800',
'access-control-allow-methods': 'GET,OPTIONS',
'correlation-id': 'f10a4f9b-0538-4dd5-bdc0-9069f90558ad'
},
config: {
url: 'https://api.dhl.com/location-finder/v1/find-by-address',
method: 'get',
params: [Object],
headers: [Object],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit newTOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
data: undefined
},
**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
request: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 6,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [TLSSocket],
connection: [TLSSocket],
_header: 'GET /location-finder/v1/find-by-address HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'DHL-API-Key: ****************************\r\n' +
'User-Agent: axios/0.19.2\r\n' +
'Host: api.dhl.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
method: 'GET',
insecureHTTPParser: undefined,
path: '/location-finder/v1/find-by-address',
_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: [Object] }
},
isAxiosError: true,
toJSON: [Function]
}
It is a breaking change from axios version 0.19.
If you would like to add a parameter to a request you have to pass it via an interceptor.
As example:
const axios = require('axios');
// api openexchange
const oexchange = axios.create({
baseURL: 'https://openexchangerates.org/api/',
timeout: parseInt(process.env.TIMEOUTEXTERNALREQUEST)
})
oexchange.interceptors.request.use((config) => {
config.params = config.params || {};
config.params.app_id = process.env.OPENEXCHANGEAPITOKEN // <-- here add the query params in your case it will be countryCode
return config;
});
exports.cotacao = async (req, res) => {
try {
req.oexchange = await oexchange.get('latest.json') //here i'm calling external api with query params added in interceptor
return res.status(200).json(req.oexchange.data)
} catch (e) {
res.status(500).json({errors: [{ location: 'cotacao', msg: 'Houve um erro ao acessar a api do open exchange.', param: 'openexchangerates' }]})
}
}
It is a know behavior that was added in version 0.19 (May 30, 2019)
Currently there is a community effort to fix that behavior you can follow here, it is addressed to be fixed in release 0.20.
If you would like the old way of passing in url params you should use version 0.18 backwards.
Every code here is based in axios documentation

Uploading Stream to Aws S3 not working Properly

I am trying to Upload stream to AWS s3. now my File Manager can upload stream of objects on server without any load or bloating. But when it comes to AWS s3 it returns successful response and even AWS SDK is not reporting anything about misconfiugration it also returns Successful Upload so my File Manager is fine But. Problem is that when i take a look on AWS Console i only see path of given file not file itself..For better Understanding Please take a look at following code and Images.
Stream to Upload (File)
ReadStream {
_readableState: ReadableState {
objectMode: false,
highWaterMark: 65536,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: null,
pipesCount: 0,
flowing: null,
ended: false,
endEmitted: false,
reading: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
emitClose: false,
autoDestroy: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null,
[Symbol(kPaused)]: null
},
readable: true,
_events: [Object: null prototype] {
end: [ [Function], [Function: remove] ],
error: [Function],
close: [Function: remove]
},
_eventsCount: 3,
_maxListeners: undefined,
path: '/tmp/capacitor-7957c2e3611868508c7ac8ec64c1a7c2.tmp',
fd: null,
flags: 'r',
mode: 438,
start: undefined,
end: Infinity,
autoClose: true,
pos: undefined,
bytesRead: 0,
closed: false,
name: undefined,
_writeStream: WriteStream {
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: true,
needDrain: false,
ending: true,
ended: true,
finished: true,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
afterWriteTickInfo: null,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: true,
errorEmitted: false,
emitClose: false,
autoDestroy: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object]
},
writable: false,
_events: [Object: null prototype] { error: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
path: '/tmp/capacitor-7957c2e3611868508c7ac8ec64c1a7c2.tmp',
fd: 30,
flags: 'w',
mode: 438,
start: undefined,
autoClose: false,
pos: undefined,
bytesWritten: 46355,
closed: false,
_readStreams: Set { [Circular] },
error: null,
_cleanupSync: [Function],
[Symbol(kCapture)]: false,
[Symbol(kIsPerformingIO)]: false
},
error: null,
[Symbol(kCapture)]: false,
[Symbol(kIsPerformingIO)]: false
}
FileManager AWS S3 Code
if (this.configuration.Aws && this.configuration.Aws.s3 && this.configuration.Aws.s3.accessKey && this.configuration.Aws.s3.secretKey) {
// Local variable.
let _Aws, _StreamUpload
// Upload file to s3
_Aws = new Aws.S3({
'accessKeyId': this.configuration.Aws.s3.accessKey,
'secretAccessKey': this.configuration.Aws.s3.secretKey
})
/*
* Only successful upload
* reply to client else report
* failure.
*/
if (!_.isEmpty(_Aws) && !(_Aws instanceof Error)) {
console.log('erw---rer>>', file)
/*
* Steam upload to aws.
* upload file to aws.
*/
_StreamUpload = await new Promise((__resolve, __reject) =>
// Upload file stream to aws s3
_Aws.upload({
'Bucket': this.configuration.Aws.s3.bucketName,
'Key': path,
'Body': file
}, (error, __data) => error instanceof Error ? __reject(error) : __resolve(__data)))
/*
* Only return _StreamUpload if
* uploading didnt contain any error.
*/
if (_StreamUpload && !(_StreamUpload instanceof Error)) {
// Return upload.
return { 'storageType': 's3', 'path': _StreamUpload.Location }
}
// Report failure.
return _StreamUpload
}
// Report failure.
return _.isEmpty(_Aws) ? new Error('UPLOAD_FAILED(AWS)') : _Aws
}
AWS S3 Response
{
ETag: '"1ea966ff33714024a163d51e06b9bad8"',
Location: 'https://truckpe.s3.amazonaws.com//ck7ef9esk000k0758t9r3mngq/1585455100505/',
key: '/ck7ef9esk000k0758t9r3mngq/1585455100505/',
Key: '/ck7ef9esk000k0758t9r3mngq/1585455100505/',
Bucket: 'truckpe'
}
AWS S3 Console Screen Shot

Axios api proxy on nuxt doesn't work on server side rendering on now zeit deploy

Following the Axios NuxtJS config, I created a proxy config like this on my nuxt.config.js:
proxy: {
'/api/': {
target: 'https://myapidomain.com/',
pathRewrite: { '^/api/': '' },
changeOrigin: true
}
}
This config works perfectly on dev environment, both server side rendering and client side rendering. Here is the code we use to create an api wrapper api.js:
export default (context, inject) => {
inject('api', {
getPageForSlug: (slugRoute) => {
return context.$axios.$get(`/api/pageForSlug?routeName=${slugRoute}`)
},
})
}
and then from any vue class:
const response = await app.$api.getPageForSlug(params.slug_route)
the only problem occurs when this code is called from the zeit now deployment. The client side works perfectly, but the server side returns this error:
START RequestId: dd92dbad-135f-414b-bc1d-df9faffaa681 Version: $LATEST
2019-08-30T17:46:03.098Z dd92dbad-135f-414b-bc1d-df9faffaa681 INFO λ Cold start took: 5265.617811ms
END RequestId: dd92dbad-135f-414b-bc1d-df9faffaa681
REPORT RequestId: dd92dbad-135f-414b-bc1d-df9faffaa681 Duration: 438.53 ms Billed Duration: 500 ms Memory Size: 3008 MB Max Memory Used: 92 MB
N',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
data: undefined },
request:
Writable {
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
emitClose: true,
autoDestroy: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object] },
writable: true,
domain: null,
_events:
[Object: null prototype] { response: [Function], error: [Function] },
_eventsCount: 2,
_maxListeners: undefined,
_options:
{ protocol: 'http:',
maxRedirects: 21,
maxBodyLength: 10485760,
path: '/api/pageForSlug?routeName=lud_form',
method: 'GET',
headers: [Object],
agent: undefined,
auth: undefined,
hostname: 'localhost',
port: '3000',
nativeProtocols: [Object],
pathname: '/api/pageForSlug',
search: '?routeName=lud_form' },
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest:
ClientRequest {
domain: null,
_events: [Object],
_eventsCount: 6,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Socket],
connection: [Socket],
_header:
'GET /api/pageForSlug?routeName=lud_form HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nx-now-deployment-url: lps-5fxmi58fz.now.sh\r\nx-now-trace: staging-gru1\r\nx-real-ip: 177.45.65.235\r\nx-zeit-co-forwarded-for: 177.45.65.235\r\nupgrade-insecure-requests: 1\r\nx-forwarded-proto: https\r\nx-now-id: 7xllz-1567187175018-d0ce35475a9e\r\naccept-encoding: gzip, deflate\r\nuser-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36\r\nx-forwarded-for: 177.45.65.235\r\nx-forwarded-host: lps-danicuki.playax.now.sh\r\ndnt: 1\r\naccept-language: en-US,en;q=0.9\r\nconnection: close\r\nHost: localhost:3000\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
timeout: undefined,
method: 'GET',
path: '/api/pageForSlug?routeName=lud_form',
_ended: false,
res: null,
aborted: undefined,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable: [Circular],
[Symbol(isCorked)]: false,
[Symbol(outHeadersKey)]: [Object] },
_currentUrl: 'http://localhost:3000/api/pageForSlug?routeName=lud_form' },
response: undefined,
isAxiosError: true,
toJSON: [Function] }
END RequestId: 6e355938-32d5-459a-adf7-08fb97101e29
REPORT RequestId: 6e355938-32d5-459a-adf7-08fb97101e29 Duration: 281.53 ms Billed Duration: 300 ms Memory Size: 3008 MB Max Memory Used: 117 MB
RequestId: 6e355938-32d5-459a-adf7-08fb97101e29 Error: Runtime exited with error: exit status 1
Runtime.ExitError
How to make the server side API request work on all environments?
This can be achieved using a rewrite in your now.json Vercel file. No need for a hack.
{
"version": 2,
"builds": [
{
"src": "nuxt.config.js",
"use": "#nuxtjs/vercel-builder",
"config": {}
}
],
"rewrites": [
{
"source": "/api/:match*",
"destination": "https://myapidomain.com/:match*"
}
]
}
Are you ready for the ultimate hack?
This is actually a common issue. When calling zeit now, a server doesn't actually get propped up. As such, you'll need to do it yourself.
The only time I've encountered a need to do this, I used express to solve it. A quick and dirty solution is to create another script (proxy.js), and have something like so:
import express from 'express'
import proxy from 'express-http-proxy'
const app = express()
app.use('/', proxy(`https://myapidomain.com`))
export default app
This does nothing but set up a reverse proxy to your API.
From there, in your zeit config, find your builds key if you have one, and replace it with this:
"builds": [
{ "use": "#now/next", "src": "package.json" },
{ "use": "#now/node", "src": "proxy.js" }
]
This will prop up and execute proxy.js when you build using zeit now.
Do note that this does mean you'll need to get the host in proxy.js to match the "normal" host. If you know the format of your config file (which you should), it may be possible to import and parse that in order to have one source of truth.
Let me know if this worked.

Categories