So im working on a SPA with Vue and want to make a axios request on the server (Laravel). The Cors problem between Vue and Larave has been taken care of.
This App should then send a Guzzle Request to another Application of ours (vanilla Php). When im doing this from the Laravel App with a console command everything works as expected.
However when im doing this in the browser (so from the SPA) everything works until the Laravel App sends the request to the plain PHP Server. Before entering the first line of php everything breaks and nginx crashes. The request is pending forever. I have to restart nginx to use it again.
When im doing the request to the plain Php App directly from the Vue SPA (axios) everything is working as it should. Only when there is a 3rd party involved everythings breaks down on the 2. request.
Maybe i need to send some Headers? Do have to tweak nginx? Something else?
Thanks in advance for your help.
Setup : laragon (nginx) on a windows machine
Vue
sendRequest(context, request){
return new Promise((resolve, reject) => {
axios.post('http://sampleurl.dev/api', {
'id': request.id,
})
.then(response => {
resolve(response)
})
.catch(error => reject(error))
}
Laravel
function create(Request $request){
$client = new Client();
$resp = $client->request('POST', 'http://sampleurl-plainphp.dev/api', [
'form_params' => [
'test' => 'test'
]
]);
return response()->json($resp, 200);
}
Related
I have developed an API project on Laravel with Sanctum (Token) and NextJs for the frontend. I have setup things up correctly and everything is working fine on Localhost.
I deployed the project on Laravel Forge with one custom subdomain (eg. api.example.com). I run php artisan storage:link and php artisan migrate:fresh --seed (with env as staging) as per their guide (cd /to the path && artisan command) and this works. FRONTEND_URL in env has also been updated to the live frontend url (eg. nextjs.example.com).
I tried logging in to the backend from nextjs after deploying Backend on Laravel Forge and NextJs on Vercel. https://api.example.com/sanctum/csrf-cookie is working correctly as it responds to the browser with the XSRF-TOKEN. But it fails on login with csrf-token mismatch.
Then I tried logging into it with Postman and the same thing happens. I can request the csrf-cookie separately but can not log in to the api backend with responded token. However, it is working fine on the localhost.
This is a piece of my working codes on localhost (NextJs)
const csrf = () => axios.get('/sanctum/csrf-cookie');
const login = async (loginDetails, setErrors) => {
setErrors('');
await csrf();
await axios
.post('/login', loginDetails, {
headers: {
'X-XSRF-TOKEN': getCookie('XSRF-TOKEN'),
},
})
.then(async (res) => {
if (res.data.status === 401) {
setErrors(res.data.message);
} else {
localStorage.setItem('user_token', res.data.data.token);
setCookie('user_token', res.data.data.token);
await axios
.get('/api/authenticated-user', {
headers: {
Authorization: `Bearer ${localStorage.getItem('user_token')}`,
},
})
.then((res) => {
localStorage.setItem(
'user_data',
JSON.stringify(res.data.data)
);
});
router.push('/dashboard/);
}
})
.catch((err) => {
setErrors(err.response.data.message);
});
};
I got the solution for this.
The reason it is not working on Postman is that X-Requested-With: XMLHttpRequest & X-XSRF-TOKEN: {{csrf-token}} were missing on the headers after duplicating the one that works on localhost for the live version. If you are experiencing the same issue, please double-check whether those headers are present on the request's headers. Then, it started working on Postman but not on the live NextJs project with the subdomain.
To make it work perfectly on the subdomain, please check this thread since I created a different question at the same time with the purpose of making it clear for the ones who wanted to answer.
There are loads of posts around the Internet related to this so I apologise if I've missed the answer here, but I seem to be going round in circles even after looking at all the existing answers. I'm clearly overlooking something.
I have a Laravel app which was recently upgraded from 6 to 8 which is being served locally under api.company-name.local. I also have a separate Vue front-end SPA being served under app.company-name.local:8080. I seem to get a successful response after getting the cookie, however when I hit my login endpoint I get a 419 - CSRF Token Mismatch response.
Setup
The Laravel app sits containerised locally with Docker, front-end simply being served up with npm run serve and I have entries in my hosts file for:
127.0.0.1 api.company-name.local
127.0.0.1 app.company-name.local
Front-End
I make a request to api.company-name.local/sanctum/csrf-cookie from within the front-end app which returns a 204 response, and then make a POST request to my login endpoint to authenticate the user.
const login = async () => {
await axios.get('/sanctum/csrf-cookie')
.then(() => {
axios.post('/loginUser', {
username: 'my-username',
password: 'my-password',
})
})
}
Observing the login POST request, I can see two cookies being sent in the request headers.
In my main.ts file I have configured the following axios defaults:
axios.defaults.withCredentials = true
axios.defaults.baseURL = 'http://api.my-company.local'
Back-End
I have updated my .env file to the following:
SESSION_DRIVER=cookie
SESSION_DOMAIN=app.company-name.local (have also tried .company-name.local)
SANCTUM_STATEFUL_DOMAINS=app.company-name.local:8080
I have added the appropriate middleware to the kernel:
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
My cors.php file is updated with these details:
'paths' => [
'api/*',
'sanctum/csrf-cookie',
'/loginUser',
'/logout',
],
'supports_credentials' => true,
When the user hits that login endpoint they'll hit this particular route setup, which uses the web middleware:
Route::group([
'module' => 'Users',
'middleware' => ['web'],
], function () {
Route::post('/loginUser', 'UsersController#login');
});
It doesn't seem to matter what I change here, I still end up with the 419 so I'm missing something here. Can anyone shed any light on what the problem could be?
I'm trying to do a https request to call a server-hosted PHP file in my react native app, so I tried this way:
fetch('https://XXX.XXX.XX.XXX/m_getApplications.php?offset=0&dateOrder=date_created')
.then((response) => response)
.then((responseJson) => {
console.warn(responseJson);
})
.catch((error) => {
console.error(error);
});
but the only thing I can get is a 404 error page from CPanel.
But the crazy thing is that when I call the SAME link on Postman (http request tool), I'm getting my JSON and everything is working well. I thought that it could be the emulator, but I tried on iOS & Android and both of them are getting the error.
I already set the NSAllowsArbitraryLoads on true but there's no way.
Has anyone encountered the problem already?
Thanks in advance for your help.
Got it! I tried with the domain name instead of the ip address of the server, and it's working now.
I have this strange issue where making a POST request to my production server results in the response I have defined for the GET request to the same route. POST works fine for my local development server. Here's the code I'm using:
routes/web.php:
$router->get('/', function () use ($router) {
return "Lumen is running.";
});
$router->group(['prefix' => 'v1'], function($router)
{
$router->get('message','MessageController#index');
$router->post('message','MessageController#create');
});
So, when I send a POST request to productionurl.com/v1/message, create() isn't executed, but when I send the exact same request to developmenturl.com/v1/message, it is.
I've tried deleting all routes but the POST one, this results in a MethodNotAllowedHttpException on the production server.
I've setup PHP7.0, Nginx and MongoDB manually on a Ubuntu 16.04 VPS.
Development server is a Homestead VM with PHP7.1 and Nginx, with MongoDB running on my host computer.
I have a working PHP app running in Bluemix that I want to extend to call a RESTful service (Insights for Twitter). Since PHP has no built-in way to call the service, I looked around and decided to use Guzzle.
I downloaded Guzzle 6.0.2 from its Git and imported the zip into my httdocs/vendor path and renamed the imported path GuzzleHttp I changed my buildpack to get PHP 5.5 and updated composer.json to the Autoload.psr4 property with:
"GuzzleHttp\\": "htdocs/vendor/"
I redeployed my app and it still worked.
Then I added the following code to my MainController.php: after some other uses:
use GuzzleHttp\Client;
and then later:
$client = new GuzzleHttp\Client([
// Base URI is used with relative requests
'base_uri' => 'https:myserviceURI.mybluemix.net',
// You can set any number of default request options.
'timeout' => 2.0,
]);
// Use guzzle to send a GET request to Watson Twitter Insights
$guzzleresponse = $client->request('GET', '/api/v1/messages/search');
Now, when I redeploy the app I get:
FatalErrorException in HomeController.php line 100:
Class 'App\Http\Controllers\GuzzleHttp\Client' not found
I don't know why it's looking in app\Http\Controllers\ but I tried copying the Guzzle src folder - which includes Client.php - there, renamed it GuzzleHttp and it still fails the same way.
I'm neither a PHP nor a Laravel expert. I inherited the code from an intern team so I don't quite know how all the pieces fit together.
I have some questions:
Did I really need to install Guzzle in my workspace or would it be picked up automatically from the buildpack?
Did I import the Guzzle code in the right way?
Why is it looking for the Guzzle Client in my Controllers path?
Is there a good PHP sample program that drives Insights for Twitter? I found one in Javascript but I need to run this server-side?
And of course, most importantly, what do I need to do to get this working?
Answers to any or all of these questions wold be greatly appreciated
Since you added
use GuzzleHttp\Client;
You have to use Guzzle Client like this:
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https:myserviceURI.mybluemix.net',
// You can set any number of default request options.
'timeout' => 2.0,
]);
It tries to look for Guzzle Client in the Controllers path probably because your controller namespace is App\Http\Controllers and you are trying to use Guzzle client like new GuzzleHttp\Client
$client = new Client(array_merge([
'base_uri' => 'URL',
'timeout' => 30.0
]), $options);
/if you need options/
$options = array_merge_recursive([
RequestOptions::AUTH => [
'Conversation_USERNAME',
'CONVERSATION_PASSWORD',
],
RequestOptions::HEADERS => [
'Content-Type' => 'application/json'
]
], $options);