I have a nextjs application, I've implemented an api endpoint under the path
src/pages/api/[[...media]].ts
the configuration for this api endpoint is as follow
export const config = {
api: {
// Enable `externalResolver` option in Next.js
externalResolver: true,
bodyParser: false,
responseLimit: false
}
};
My handler is just a test print
export default async (req: NextApiRequest, res: NextApiResponse) => {
console.log(`OK`);
....
If do a POST request with a Multipart form-data attached to the request and the file is small it works, otherwise if the file is more than 1MB (that is the default limit on nextjs) the POST request hungs.
I assumed that the config bodyParser: false disabled the automatic body parser and also the limit https://nextjs.org/docs/api-routes/request-helpers
Related
I am building a web application with a go backend and a vue.js frontend.
I want to do a simple sign in form in which I send the sign in request from a method of my component with Axios (or fetch) and get in response a JSON object of the user and a session token in the cookie to be stored and reused in future requests to the server.
The code of my components method :
class LoginComponent extends Vue {
sendLogin (): void {
axios.post<User>('http://192.168.1.227:8080/signin', body)
.then(res => console.log('Axios Response :', res)
.catch(err => console.error('Axios Error :', err))
}
}
The part of the code of the go server :
go API
with the headers :
go headers
the front and backend are on different IP addresses in a local network and they communicate through HTTP.
The problem that I faced is that when receiving the response after the post request to login I don't have access to the cookie that has been set by the server. When I use Axios to analyze the response the cookie isn't in the headers whereas when I look at the network logs in the browser, the cookie is in the headers but it is not saved and it is not sent when I do another request.
Also, the only header that is visible with Axios is Content-Type : application/json; charset=UTF-8
I tried many things to be able to see this cookie but it doesn't work :
adding { withCredentials: true } to the axios request or axios.defaults.withCredentials = true to the axios instance only stops the request because of CORS.
changing all the Access-Control headers to "*" didn't change anything
using { auth: { username: 'foo', password: 'bar' } } in the axios options instead of the body
The only thing that worked and automatically saved the cookie was to send the request via the attributes of the form html tag, like so :
<form method="POST" action="http://192.168.1.227/signin">
...
</form>
But this way I am redirected to the JSON response object and not to one of my routes from vue-router and I can't access the User object in my app.
Is there any way that my problem can be solved?
Ok so the comment of Зелёный was the answer.
I needed the go server to set Access-Control-Allow-Origin: http://192.168.1.218:8080 (the address of the frontend) and then configure axios with { withCredentials: true } to be able to automatically store the cookie. Although I still don't see it when I do a console.log on the axios response, it is successfully stored and reused for each call to the server.
When I am making a request, axios is attaching the whole cookie along with it.
I have already tried
withCredentials: false
And
axios.defaults.withCredentials = false;
Still its sending the cookies...
This is where I am creating the request..
import axios from 'axios'
// create an axios instance
const service = axios.create({
baseURL: '/api/v1/', // url = base url + request url
withCredentials: false, // send cookies when cross-domain requests
timeout: 5000 // request timeout
})
Its still sending the cookie with it
Please help
I am developing a new frontend using Vue to access my existing Laravel 7 app, which uses Sanctum for authentication.
The frontend sits on app.example.com, with the backend being moved to api.example.com. The CORS middleware and Sanctum are properly configured to allow app.example.com, and so far so good.
The GET to /sanctum/csrf-cookie looks fine, however, it doesn't seem to be actually setting the cookies, causing the subsequent request to the API to return a 419.
const config = { withCredentials: true };
const api = process.env.NODE_ENV === 'production' ? 'https://api.example.com' : 'http://localhost:9000';
axios.get(api + '/sanctum/csrf-cookie', config)
.then(() => axios.post(api + '/login', data, config))
.then(response => response.json())
.then(response => { console.log('json', response); });
Console log:
Response headers from /sanctum/csrf-cookie:
No cookies are listed in devtools:
UPDATE 1: Didn't notice this earlier; the warning icons next to each Set-Cookie in the response headers display "This set-cookie's Domain attribute was invalid with respect to the current host url."
Short answer: Ports should not be specified in cookie domain attributes.
Long answer: Laravel Sanctum uses the VerifyCsrfToken middleware to both send and verify the CSRF token, which uses session config values when adding the cookie to the response:
protected function addCookieToResponse($request, $response)
{
$config = config('session');
if ($response instanceof Responsable) {
$response = $response->toResponse($request);
}
$response->headers->setCookie(
new Cookie(
'XSRF-TOKEN', $request->session()->token(), $this->availableAt(60 * $config['lifetime']),
$config['path'], $config['domain'], $config['secure'], false, false, $config['same_site'] ?? null
)
);
return $response;
}
In config/session.php:
'domain' => env('SESSION_DOMAIN', null),
In .env:
SESSION_DOMAIN=localhost:8080
Cookies on the same host ARE NOT distinguishable by ports. Because I had specified the port in the cookie domain, the browser had flagged the cookie as having an invalid domain. Removing the port did the trick.
For me to solve the problem I changed my vue cli host which was 127.0.0.1:8080 to localhost:8080 in browser,and within axios the base url is now http://localhost:7000 which is for laravel api.
after that I then set SESSION_DOMAIN=localhost in .env laravel
I had a small node server and I use the framework fastify.
In one of my routes, I want to get the data from a third party API.
I tried the following snippet:
fastify.route({
method: 'GET',
url: 'https://demo.api.com/api/v2/project/',
handler: async function ({ params, body}, reply) {
if (!body) return reply.send({ sucess: false })
console.log('testing')
console.log(body)
return reply.send({ sucess: true })
}
})
Unfortunately, I cannot call the URL by get because GET url's can only start with '/'.
How do i call a third pary api via fastify? do i need a extention?
If you need to define a route (like http://localhost:3000/) that proxies another server you need to use fastify-http-proxy.
Or if you need to call another endpoint and manage the response, there is the fastify.inject() utility but it is designed for testing.
Anyway, I think the best approach is to use some HTTP client like got
const got = require('got') // npm install got
fastify.get('/my-endpoint', async function (request, reply) {
const response = await got('sindresorhus.com')
console.log(response.body)
// DO SOMETHING WITH BODY
return { sucess: true }
})
Proxy your http requests to another server, with fastify hooks.
here is the example in fastify-http-proxy
server.register(require('fastify-http-proxy'), {
upstream: 'http://my-api.example.com',
prefix: '/api', // optional
http2: false // optional
})
https://github.com/fastify/fastify-http-proxy/blob/master/example.js
How do I make an http request to a webservice on document load using cyclejs?
The examples cover reacting to user input and don't meet my needs.
You may try to create a request stream and pass it to the HTTPDriver.
For example:
const request$ = Rx.Observable.just({
url: 'http://www.google.com',
method: 'GET'
});
Then:
return {
HTTP: request$
};