I have an web app which I bundled using webpack, I placed my entire react/redux app in the public file which will be served by nodejs(express-generator). My app works when I run in localhost/ local env. However when I deploy to heroku. I cannot make calls.
The below is the error message:
bundle.js:19 GET https://glacial-cove-64389.herokuapp.com/users/ 401 (Unauthorized)
Object {err: Error: Request failed with status code 401 at e.exports (https://glacial-cove-64389.herokuapp.co…}
err
:
Error: Request failed with status code 401 at e.exports (https://glacial-cove-64389.herokuapp.com/bundle.js:19:10382) at e.exports (https://glacial-cove-64389.herokuapp.com/bundle.js:26:6821) at XMLHttpRequest._.(anonymous function) (https://glacial-cove-64389.herokuapp.com/bundle.js:19:9464)
__proto__
:
Object
initially I thought it could be my my ROOT_URL so I changed it the below is an example of my actions file.
const ROOT_URL = "//glacial-cove-64389.herokuapp.com"
const axiosOption = {headers: { authorization : localStorage.getItem('token')}}
/*Sign in user*/
export function signinUser({ email, password }){
return function(dispatch){
axios.post(`${ROOT_URL}/users/signin`, { email, password })
.then(function(res){
dispatch({ type: AUTH_USER })
localStorage.setItem('token', res.data.token);
browserHistory.push('/users');
})
.catch(function(err){
dispatch(authError('Invalid email or password'))
console.log({err});
})
}
}
So what happens is that the react recognize the login and push user to the correct route. but it return the above error msg status code 401 once it hits the main pages.
The main problem I have is when I try to perform CRUD which doesn't work
Here is my repo: https://github.com/boyboi86/API_basic_random
I found out the hard way..
If you intend to put everything within your public file when scaffold with express-generator. Putting CORS within your Nodejs is insufficient because now your axios (react) that makes the call is also subjected to CORS, And you will have to config within your axios with the following:
axios.defaults.headers.post['Access-Control-Allow-Methods'] = 'PATCH, DELETE, POST, GET, OPTIONS';
This is to ensure all calls made will be allowed. I realised this when I look at the response headers.
Related
I'm trying to create a form where the user fills in some data and after that the data is submited to the server
methods: {
sendOrder () {
this.loading = true;
axios.post ('/send/', {
firstName: this.firstName,
lastName: this.lastName,
phone: this.phone,
delivery: this.delivery,
... (this.delivery? {address: this.address}: {}),
note: this.note,
items: this.items,
total: this.total
})
this works great on my local server, however when i set up on the real server i get the following error in the console:
http://my-website.com/email-sender/public/send 405 (Method Not Allowed)
I doubt this part of the response where you can see ...email-sender/public...
Is this possible due to the wrong .htaccess setting?
Also, when I make a post request to this same route via postman I get this error:
Status: 419 unknown status
it doesn't matter if i send the request to http://my-webiste.com/send or
http://my-webiste.com/public/email-sender/send the error on postman is allways 419.
Routes (from comment):
Route::get('/', 'OrderController#index');
Route::get('/thankyou', 'OrderController#thankyou');
Route::post('/send', 'OrderController#send');
I solved the problem. Specifically, the problem was in the .htaccess file, which did not point well to the public root of the Laravel application.
Previously, I had a public folder and a Laravel project folder in it, which I had to change in order for all Laravel files to be in that root folder.
Now the problem with displaying the entire path in the url disappeared as well as the problem with code 419. I hope I explained the solution to the problem properly.
This question already has answers here:
Access-Control-Allow-Origin with instagram api
(1 answer)
CORS error, when i use instagram API with angularjs
(1 answer)
Closed 3 years ago.
I'm trying to fetch some images from my Instagram account in a Laravel application with Vue as front end. When I try to do it in a standalone Vue app, it works well, but when I do so with Laravel, I got a message saying "has been blocked by CORS policy: Request header field x-csrf-token is not allowed by Access-Control-Allow-Headers in preflight response."
I'm using Laravel 5.8 and the Vue and Axios that comes within in and I'm using Homestead as my localhost server.
I've tried a lot of tips that I found here and on Google but I had no success. Basically, I'm trying the very basic of Axios call
beforeMount() {
axios.get('https://api.instagram.com/v1/users/self/media/recent/?access_token=[MY_ACCESS_TOKEN]').then(response => console.log(response))
}
I already created a Cors middleware on Laravel and tried a lot of headers settings on Axios.
I'm basically trying to retrieve a list of my Instagram posts and bypass that cors / x-csrf error.
Laravel automatically applies the X-CSRF-TOKEN header to all axios requests. This is so you can communicate with your application without having to pass the CSRF token every time for POST, PUT, DELETE, etc.
resources/js/bootstrap.js (default settings)
/**
* Next we will register the CSRF Token as a common header with Axios so that
* all outgoing HTTP requests automatically have it attached. This is just
* a simple convenience so we don't have to attach every token manually.
*/
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
You should be able to remove the offending header by doing something like this:
beforeMount() {
// create a new instance so we don't delete the csrf token for other requests
let instance = axios.create();
// delete the x-csrf-token header
delete instance.defaults.headers.common['X-CSRF-TOKEN'];
// use the new instance to make your get request
instance.get('https://api.instagram.com/v1/users/self/media/recent/?access_token=[MY_ACCESS_TOKEN]')
.then(response => console.log(response))
}
Your AJAX request to the Instagram API endpoint has to be sent as a jsonp request which means the dataType of the request has to be jsonp.
This blob in axios repository contains an example of sending a request using jsonp which is mentioned below.
Install jsonp package, if you haven't already.
npm install jsonp --save
and then;
const jsonp = require('jsonp');
jsonp('http://www.example.com/foo', null, (err, data) => {
if (err) {
console.error(err.message);
} else {
console.log(data);
}
});
Below is an example of sending a request using jQuery method with jsonp dataType to the Instagram API endpoint.
$.ajax({
url: "https://api.instagram.com/v1/users/self/media/recent/?access_token=[MY_ACCESS_TOKEN]",
type: "GET",
crossDomain: true,
dataType: "jsonp",
success: function(response){
console.log(response);
}
});
I am using Nuxtjs and built-in Vuex modules along with Nuxtjs's official axios. I'm trying to GET from my local server and it always throw CORS error.
So I made an API call to Github's public endpoint, and unsuccessfully only getting CORS error in my console.
I'm using Store actions to launch AJAX calls to server on component create lifecycle. Here is my code.
// component.vue
created () {
this.$store.dispatch('getGithubAPI')
}
// store action
async getGithubAPI ({ commit, state }) {
await this.$axios.$get('https://api.github.com/users/kaungmyatlwin', { headers: { 'Access-Control-Allow-Origin': '*' } })
.then(resp => {
console.log(resp.data)
})
}
Still no luck of getting it. Here is an error message that was thrown to console.
Failed to load https://api.github.com/users/kaungmyatlwin: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:3000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
What did I do wrong here? Or is it an error residing in async/await?
UPDATE: Strange thing is that the network call actually goes out and fetch data from server, as it can be seen in Network console from Chrome.
Ok I seem to have figured out this problem.
In nuxt.config.js, you have to put credentials: false to allow CORS wildcard.
My axios config here.
axios: {
baseURL: 'https://api.github.com',
proxyHeaders: false,
credentials: false
}
Reference: https://github.com/nuxt-community/axios-module#credentials
I'm making a client-side request out to V2 of the Square API using Vue and Axios. My Vue component is as follows:
import axios from 'axios';
export default {
mounted() {
var instance = axios.create({
baseURL: 'https://connect.squareup.com/v2/',
timeout: 1000,
headers: {
'Authorization': 'Bearer xxxxxxxxxxxxxxxxx',
'Accepts': 'application/json',
'Content-Type': 'application/json'
}
});
instance.get('catalog/list')
.then(function (response) {
console.log(response);
}) ;
}
}
However, when I make that call, I receive the following error:
Failed to load https://connect.squareup.com/v2/catalog/list: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://local-env.dev' is therefore not allowed access. The response had HTTP status code 403.
That error suggests that there is some configuration that has to happen on the Square side, but I saw no opportunity to whitelist domains, etc.
Has anyone come across this error before, regardless of service, and if so, how did you resolve?
I don't think the Square API supports being called from a browser. I used Postman to do an OPTIONS request on https://connect.squareup.com/v2/catalog/list and the response was a NOT_FOUND. The OPTIONS request is needed for proper CORS support.
Plus, if you did this, I would think your auth token would need to be sent to the client -- thus exposing it to everyone. It looks like the Square API is only designed to be called from a server. But that is just based on me skimming the docs a bit. I have no experience using their API.
When doing OAuth authorization request you are not supposed to do it from your application. Create and URL with the parameters and open it in a new browser window or tab, Something like:
const grants='MERCHANT_PROFILE_READ CUSTOMERS_READ CUSTOMERS_WRITE PAYMENTS_READ PAYMENTS_WRITE PAYMENTS_WRITE_ADDITIONAL_RECIPIENTS PAYMENTS_WRITE_IN_PERSON';
const params = new HttpParams()
.set('scope', grants)
.set('client_id', <YourSquareApplicationId>)
.set('state', '1878789');
const requestUrl = `${<squareUrl>}/oauth2/authorize?${params.toString()}`;
window.open(requestUrl, "_blank");
That new window is supposed to ask the end user to login to his account and accept or deny the request.
I'm using the following lua script to forward all server responses that are served from Node. My error handling for a /signup route works as follows:
if authenticationResult.status ~= 201 then
...
ngx.status = authenticationResult.status
ngx.say(authenticationResult.body)
ngx.exit(401)
return
end
From the client I send a typical signup request like so, using the superagent-promise library:
request
.post(url)
.type('form')
.send(data)
.end()
.then((response) => {
console.log('the response', response)
})
.catch((error) => {
console.log('the error', error)
})
When I send a valid post request from the client, the response variable in the .then successfully contains the response body.
However, when I sent an improper post request with invalid credentials, neither the .then nor the .catch executes. Instead, the Chrome console immediately displays POST http://api.dockerhost/signup 401 (Unauthorized).
I would like to know what I can do differently to successfully access the server's error response and its contents, outside of just its status code.
Per the manual, you need to use ngx.HTTP_OK as the return if you want nginx to return content as part of the page. Otherwise it will simply return a 401.
ngx.status = authenticationResult.status
ngx.say(authenticationResult.body)
ngx.exit(ngx.HTTP_OK)
return