I have a problem with CORS in laravel and vueJS. i need send parameter to other website with my aplication in laravel, but always return error CORS. I tried create a middleware but i don´t know how i implements my routes with this.
i´m tried add header in index.php to Laravel, returned CORS, i´m tied add this code in petetition axios
let url = "/contrarBono30Min";
let bono = "Bono30Min";
axios.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
axios.post(url, {
bono: bono,
token: csrf_token,
}
)
My Controller
public function contrarBono30MinHome(Request $request){
$usuario = \Auth::user()->id;
$bono = $request["bono"];
$precioBono = \DB::select("SELECT precio FROM bonos WHERE codBono = '1'");
return redirect('.....URL?bono='.$bono.'&user='.\Auth::user()->nombre.'&nif='.\Auth::user()->nif.'&precio='.$precioBono[0]->precio);
}
action button
contratar: function(){
$(".contratar").on("click", function(e){
var bono = $(this).closest("tr").find("td:eq(0)").text();
var csrf_token = $('meta[name="csrf-token"]').attr('content');
if(bono == 1){
let url = "/contrarBono30Min";
let bono = "Bono30Min";
axios({
method: 'POST',
url: url,
data: {
bono
}
});
}
if(bono == 2){
let url = "/contrarBono1H";
axios.post(url, {bono:Bono1H})
.then((response) => {
console.log(response);
});
}
if(bono == 3){
let url = "/contrarBono5h";
axios.post(url, {bono:Bono5H})
.then((response) => {
console.log(response);
});
}
if(bono == 4){
let url = "/contrarBono10H";
axios.post(url, {bono:Bono10H})
.then((response) => {
console.log(response);
});
}
if(bono == 5){
let url = "/contrarBono24H";
axios.post(url, {bono:Bono24H})
.then((response) => {
console.log(response);
});
}
});
nothing, return CORS...
my URL in axios is external, i need to send info to other web, how pad type, price, name buyers, etc... But redirect i have a CORS ERROR
i don´t know how resolve this problem.
thanks for help
CORS FILE
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
put these lines inside your public/index.php, this is the easiest way.
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
Related
I've been hitting wall for a while now with this, simply I can't get it where is the problem. So I've got backend Laravel and front Vue; logging in is alright, I get token but when I get into one of the routes with auth:api I get "message":"Unauthenticated.". I save token on the front, so should I send it with any request to backend or there is other way around it?
LoginController.php
public function login(Request $request)
{
$login = $request->validate([
'email' => 'required',
'password' => 'required',
]);
if(Auth::attempt($login))
{
return response(['message' => 'Invalid login']);
}
$user = User::where('email', $request->email)->first();
$accessToken = $user->createToken('Laravel Password Grant Client')->accessToken;
return response()->json(['user' => $user, 'access_token' => $accessToken]);
}
api.php
Route::namespace('\\')->middleware('auth:api')->group(function(){
Route::resource('budget', BudgetController::class);
});
user.js
const state = {
token: localStorage.getItem('access_token') || null,
isAuthenticated: localStorage.getItem('access_token') !== null
}
const getters = {
isAuthenticated: state => state.isAuthenticated
}
const actions = {
async retrieveToken({commit}, payload){
console.log(payload)
const response = axios.post(url + '/login', payload)
.then(response => {
const token = response.data.access_token
localStorage.setItem('access_token', token)
commit('setToken', token)
})
}
}
const mutations = {
setToken: (token) => state.token = token
}
Alright, so simply in my second module I used token as a header like this:
const state = {
budget: [],
header: {
headers: {
Authorization: `Bearer ${localStorage.getItem("access_token") || null}`,
withCredentials: true,
"Access-Control-Allow-Origin": "*"
},
}
};
const getters = {
allBudget: (state) => state.budget,
};
const actions = {
async fetchBudget({ commit, state }) {
const response = await axios.get(url, state.header);
console.log(state.header);
commit("setBudget", response.data);
},
};
After that I was getting CORS error so i needed to add two directives at the end of the file xampp\apache\conf\httpd.conf
Header Set Access-Control-Allow-Origin *
Header Set Access-Control-Allow-Headers *
I have an app scenario with react native and CodeIgniter as backend.
I have a code snippet to upload image as picked by react-native-image-picker as below:
let formData = new FormData();
let imageBody = {
uri: newImage,
name: 'profilepicture.jpg',
type: 'image/jpeg',
};
formData.append('file', (imageBody)) // case 1 gives network error
formData.append('file', JSON.stringify(imageBody)) //case 2 goes OK
apiUpdateUser(formData)
.then(res => {
this.setState({ showSnack: true, snackText: 'Profile Picture Updated'})
})
.catch(err => {
this.setState({ showSnack: true, snackText: 'Update Failed' })
});
The apiUpdateUser method goes as :
export const apiUpdateUser = body => {
return new Promise((resolve, reject) => {
axios
.post(ApiRoutes.updateUser, body, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(res => {
resolve(res.data);
})
.catch(err => {
reject(Constant.network.networkError);
});
});
};
The Php code at the backend to handle this upload as usual is:
$file=$this->request->getFile('file');//in CI
$file=$_FILES['file'];//in normal php
My issue is that I do not get anything whatsoever in the $file variabe with either of the methods, The file variable is empty in both the cases.
I've checked the implementation in react native and it doesnt seem to be buggy at all comparing with tutorials/demonstrations online. Also the way of handling at the backend is obvious and Ok.
I'm able to achieve this upload with POSTMAN easily but with react-native I'm facing this error. Can anyone show me some light here??
I am using VUE and sending files using Axios. So I think this may help you out.
I am using the following way of form data to set the files or images.
formData.append('file', this.form.image_url, this.form.image_url.name);
Here this.form.image_url directly refers to the $event.target.files[0]; where $event targets the input.
In the backend, it is the same as you have it here.
This works out well for me. I am unsure of what you are passing as imageBody so it's hard to comment on that.
You can try this
let imageBody = {
uri: newImage,
name: 'profilepicture.jpg',
type: 'image/jpeg',
};
apiUpdateUser(imageBody)
.then(res => {
this.setState({ showSnack: true, snackText: 'Profile Picture Updated'})
})
.catch(err => {
this.setState({ showSnack: true, snackText: 'Update Failed' })
});
export const apiUpdateUser = body => {
return new Promise((resolve, reject) => {
axios
.post(ApiRoutes.updateUser, body, {
headers: {
'Content-Type': 'application/json'
}
})
.then(res => {
resolve(res.data);
})
.catch(err => {
reject(Constant.network.networkError);
});
});
};
Turns out that the JSON.stringify() was the culprit line.
Without that line, the app was giving out network error.
That's why I had randomly added it just to see if that was the cause of error.
Since, the network error issue was solved with that addition, I didn't give a second thought about it and only thought it to be a file upload issue. Actually, I now see that this is a known issue of a react native flipper version that I have been using which I managed to solve.
Please Help me, How to post data using the request which made by Vue.js
There's Vue's code
let tests = {
cat1: {
name: 'Auth',
items: {
authorize2: {
name: 'Successful',
subname: '',
request: {
method: 'POST',
link: 'auth',
data: {
login: 'admin',
password: 'password'
}
},
test: (result, status) => {
if (status.status == 200) {
return true;
}
return false;
}
}}}}
PHP page which receives this code doesn't have anything in POST data storage.
Originally Vue used the vue-resource package to perform POST requests via the $http instance property:
login(){
var data = {
login: 'admin',
password: 'password'
}
this.$http.post('/auth', data)
.then(response => { /* success callback */ }, response => { /* error callback */ })
}
In Vue2 vue-resource was retired and they started to recommend Axios. They also offered a way to override the $http instance property allowing you to invoke the axios library in a similar way.
this.$http.post('/auth', data)
.then(response => { /* success callback */ })
.catch(error => { /* error callback */ })
Or you can just load the Axios Package and call it directly:
const axios = require('axios');
...
axios.post('/auth', data)
.then(response => { /* success callback */ })
.catch(error => { /* error callback */ })
You could even choose to use vanilla js or another library like jQuery and use $.ajax() to make the request within your Vue instance, but using axios is the current recommendation from Vue.
I have a React application that connects to a back-end Laravel application that has a GraphQL layer on top of it.
I have a GraphQL query as such:
http://laravel-quarx.dev/graphql?query=query+getUserNameAndId{users{id,name}}
Which will return the following JSON:
{"data":{"users":[{"id":1,"name":"Admin"},{"id":2,"name":"Saqueib Ansrai"}]}}
Here is how I fetch this data in React (I am using Redux so I have my call in the Saga):
function* fetchProducts(actions) {
try {
const response = yield call(fetchApi, {
method: 'GET',
url: '?query=query+getUserNameAndId{users{id,name}}',
});
yield put(productSuccess(response));
} catch (e) {
yield put(productFailure(e.response ? e.response.data.message : e));
}
}
This results in the following error:
XMLHttpRequest cannot load
http://laravel-quarx.dev/graphql/?query=query+getUserNameAndId{users{id,name}}.
Redirect from
'http://laravel-quarx.dev/graphql/?query=query+getUserNameAndId{users{id,name}}'
to
'http://laravel-quarx.dev/graphql?query=query+getUserNameAndId{users{id,name}}'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource. Origin
'http://localhost:3000' is therefore not allowed access.
I am unsure as to what I have to do on my server-side application to bypass the CORS limitations, any ideas?
EDIT:
Headers:
Cors config:
return [
/*
|--------------------------------------------------------------------------
| Laravel CORS
|--------------------------------------------------------------------------
|
| allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
| to accept any value.
|
*/
'supportsCredentials' => false,
'allowedOrigins' => ['*'],
//Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Cache-Control
'allowedHeaders' => ['*'],
'allowedMethods' => ['*'], // ex: ['GET', 'POST', 'PUT', 'DELETE']
'exposedHeaders' => [],
'maxAge' => 0,
];
You have two options, one is making your application to understand cors, and the second is to disable cors in the fetch options in your apollo client:
const link = new HttpLink({
uri: 'URI',
fetchOptions: {
mode: 'no-cors'
}
});
Cors working in this api users/login problem in postjob/store api i solved this issue adding cors true in angular.
After few days i call this api again same error occur
XMLHttpRequest cannot load http://192.168.10.5/jobpost1/public/api/job. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9001' is therefore not allowed access.
Routes.php
Route::group(['prefix' => 'api'], function () {
Route::post('users/login', array('middleware' => 'Cors', 'uses' => 'Auth\AuthController#login'));
});`
Route::group(['prefix'=>'api'], function()
{
Route::group(['middleware'=>'jwt-auth'], function ()
{
Route::post('postjob/store', array('middleware' => 'Cors', 'uses'=> 'PostController#store'));
});
});
Cors.php
class Cors
{
public function handle($request, Closure $next)
{
// ALLOW OPTIONS METHOD
$headers = [
'Access-Control-Allow-Origin'=> '*',
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin',
'Access-Control-Allow-Credentials' => 'true'
];
if($request->getMethod() == "OPTIONS") {
// The client-side application can set only headers allowed in Access-Control-Allow-Headers
return Response::make('OK', 200, $headers);
}
$response = $next($request);
foreach($headers as $key => $value)
$response->header($key, $value);
return $response;
}
angular code
return $http({
method: 'POST',
url: 'http://192.168.10.4/jobpost1/public/api/job',
cors: true,
xhrFields: {
withCredentials: true
},
params: {
"token" :token,
"user_id": userId,
"job_shift": job_shift,
"job_type": job_type,
"job_description":job_description,
"degree_title": degree_title,
"city": city,
"experience": experience,
"career_level": career_level,
"gender":gender,
"total_position": total_position,
"minimum_edu":minimum_edu,
"apply_before": apply_before
}
}).then(function successCallback(response, status) {
callback(response, status);
debugger;
}
, function errorCallback(response, status) {
callback(response, status);
debugger;
});
};
Rather than adding headers using foreach:
foreach($headers as $key => $value)
$response->header($key, $value);
Give this a go instead:
$response->headers->add($headers);