CORS issue in calling userInfo from google API in react - reactjs

I am using #react-oauth/google with Implicit method of getting user info from google account.
This is the code I use
const handleGoogleLogin = useGoogleLogin({
onSuccess: async (tokenResponse) => {
console.log(tokenResponse);
const token = pathOr('', ['access_token'], tokenResponse)
const userInfo = await axios.get(
'https://www.googleapis.com/oauth2/v3/userinfo',
{ headers: { Authorization: `Bearer ${token}`, "Access-Control-Allow-Origin": window.location.origin } },
);
console.log("user",userInfo);
},
onError: errorResponse => console.log(errorResponse),
});
In the axios request, I get the following error:
Access to XMLHttpRequest at 'https://www.googleapis.com/oauth2/v3/userinfo' from origin 'https://mywebsite:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
Can anyone help fix this cors issue? Thanks!

I used XMLHttpRequest and it's working without any cors error.
const userInfo = await new Promise(resolve => {
const xhr = new XMLHttpRequest();
xhr.open('GET', `https://www.googleapis.com/oauth2/v3/userinfo`);
xhr.setRequestHeader('Authorization', `Bearer ${token}`)
xhr.onload = function () {
if (this.status >= 200 && this.status < 300)
resolve(JSON.parse(this.responseText));
else resolve({ err: '404' });
};
xhr.send();
});

Related

How to fetch customers in reactjs using shopify api

I am new to API. I want to fetch customers in reactjs using shopify customer api.
I'm using following code:
const apiUrl = `https://${process.env.GATSBY_SHOPIFY_API_KEY}:${process.env.GATSBY_SHOPIFY_PASSWORD}#${shopify-store}/admin/api/${version}/customers.json`;
useEffect(() => {
fetch(apiUrl , {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin':'*'
},
mode: 'cors',
})
.then((response) => {
console.log('response:', response);
})
.catch((error) => {
console.error('Error:', error);
});
},[])
Above code is producing error:
Url with cedentials can not be used in FETCH
I also tried using AXIOS. Code is following:
const getData = async () => {
try {
const res = await axios.get(apiUrl);
console.log("res >>>", res)
} catch(error) {
console.log("error >>", error)
}
}
Above code is also producing error:
Access to XMLHttpRequest at 'apiUrl' from origin 'http://localhost:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Please help me out with api!
Thanks in advance
I want to solve the issue as soon as possible. I have tried all the methods I could find on internet.

CORS error while trying to post data with Axios on AWS REST API configuration using a node.js Lambda function

I'm posting data to a DynamoDB table with axios in a React front-end.
The API is set up through a serverless configuration with an API Gateway and Lambda on AWS.
While the request goes through and I see the added item on the database I still get a CORS error https://i.stack.imgur.com/m7yMG.jpg
This is the axios method:
import axios from "axios";
export const sendItemToDB = async (_data) => {
if (!_data) { return };
try {
const res = await axios({
method: "POST",
url: process.env.REACT_APP_QUERY_API,
data: _data,
headers: {
"Content-Type": "text/plain"
},
});
console.log("data returned from api", res);
} catch (error) {
console.log("Error sending File to db: ");
console.log(error);
}
};
And the API method on Lambda:
const createRecord = async (event) => {
const response = { statusCode: 200 };
try {
const body = JSON.parse(event.body);
const params = {
TableName: process.env.DYNAMODB_TABLE_NAME,
Item: marshall(body || {}),
};
const createResult = await db.send(new PutItemCommand(params));
response.body = JSON.stringify({
message: "Successfully created record.",
createResult,
});
} catch (e) {
console.error(e);
response.statusCode = 500;
response.body = JSON.stringify({
message: "Failed to create record.",
errorMsg: e.message,
errorStack: e.stack,
});
}
return response;
};
I based this configuration on this tutorial : https://github.com/jacksonyuan-yt/dynamodb-crud-api-gateway
I solved this following amazon documentation and reconfiguring the serveless deployment yml.
Serverless documentation on api gateway and lambda proxy integration here
Adding the missing headers to all lambda functions was essential.
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Headers" : "Content-Type",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET"
},
};
Also testing that OPTIONS is working for the preflight:
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-test-cors.html
Just as Stavros noticed, the problem is that this is not a simple cross-origin POST method request (because it contains custom headers), so you need to tweak CORS settings of AWS API Gateway by adding
"POST, GET & OPTIONS" for Access-Control-Allow-Methods
"content-type" for Access-Control-Allow-Headers
You can do it through console like this
You also might need to add those headers in lambda like this
and it will work.

react admin returns Unauthorized 401 error upon CRUD operations

I am working on a react-admin project. The backend is written using Django rest framework which runs on a docker container. The authentication endpoints for access and refresh tokens are written using djangorestframework-simplejwt and served at http://localhost:8000/api/token/ and http://localhost:8000/api/token/refresh/ respectively.
I have written my own authProvider.js and dataProvider.js for react admin. The login and checkAuth functions for authProvider.js looks like this
// in src/authProvider.js
import jwt from "jsonwebtoken";
export default {
login: async ({ username, password }) => {
const request = new Request('http://localhost:8000/api/token/', {
method: 'POST',
body: JSON.stringify({ username, password }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
const response = await fetch(request);
if (response.status < 200 || response.status >= 300) {
throw new Error(response.statusText);
}
const { refresh, access } = await response.json();
localStorage.setItem('refreshToken', refresh);
localStorage.setItem('accessToken', access);
},
logout: ...
checkAuth: async () => {
const accessToken = localStorage.getItem('accessToken');
const refreshToken = localStorage.getItem('refreshToken');
if (accessToken && refreshToken) {
const { exp } = await jwt.decode(accessToken);
if (exp > (new Date().getTime() / 1000) - 10) {
return Promise.resolve();
} else {
const request = new Request('http://localhost:8000/api/token/refresh/', {
method: 'POST',
body: JSON.stringify({ "refresh": refreshToken }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
const response = await fetch(request)
.then(response => {
if (response.status !== 200) {
throw new Error(response.statusText);
}
return response.json();
})
.then(({ token }) => {
localStorage.setItem('accessToken', token);
return Promise.resolve();
});
return response;
}
}
return Promise.reject();
},
checkError: ...
getPermissions: () => Promise.resolve(),
}
Retrieving data works fine. But whenever I perform a create, edit and delete operation, I am automatically logged out with a 401 Unauthorized error. Error message from docker server log
Unauthorized: /api/products/2
"PUT /api/products/2 HTTP/1.1" 401
Error from browser console: PUT HTTP://localhost:8000/api/products/2 401 (Unauthorized)
Prior to adding authProvider and using docker container as backend, CRUD data mutations worked fine, using a local python venv as backend. So I assume the dataProvider.js is not responsible here.
I have not been able to figure this out for quite some time. Can anyone help me figure out what I might be doing wrong here? Thank you for your time.
EDIT 1: It seems the access token is not sent from the frontend during API request, hence the server returning 401 Unauthorized
You need to modify your dataProvider to include the token (in a token, a cookie, or in a GET parameter, depending on what your backend requires). This is explained in the react-admin auth documentation:
import { fetchUtils, Admin, Resource } from 'react-admin';
import simpleRestProvider from 'ra-data-simple-rest';
const httpClient = (url, options = {}) => {
if (!options.headers) {
options.headers = new Headers({ Accept: 'application/json' });
}
const { token } = JSON.parse(localStorage.getItem('auth'));
options.headers.set('Authorization', `Bearer ${token}`);
return fetchUtils.fetchJson(url, options);
};
const dataProvider = simpleRestProvider('http://localhost:3000', httpClient);
const App = () => (
<Admin dataProvider={dataProvider} authProvider={authProvider}>
...
</Admin>
);

Implementing google-recaptcha v3 in react without a backend

I'm a frontend developer trying to create a test case of adding google-recaptcha-v3 in my react app.
I'd appreciate response to how i can by-pass the cors error when I make a post request to verify the user's token.
//imports
...
const Recaptcha=()=>{
return(
<div>
<p>Recaptcha Test</p>
<button onClick={handleSubmit}>Send Test</button>
</div>
)
// handleSubmit function
const handleSubmit =()=>{
const getToken = async () => {
await executeRecaptcha('contactpage')
.then(res=>{
console.log(res);
return setToken(res);
});
}
getToken();
console.log(token);
const verifyToken = async () => {
console.log(token);
const article = {
secret: '*******',
response: token
}
let axiosConfig = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
"Access-Control-Allow-Origin": "http://localhost:3000",
}
};
let url = 'https://www.google.com/recaptcha/api/siteverify';
await axios.post(url, article)
.then(res => console.log(res))
.catch(err => console.log(err));
}
verifyToken();
}
Then I get this error in my browser console:
Access to XMLHttpRequest at 'https://www.google.com/recaptcha/api/siteverify' from origin 'http://localhost:3000/' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Google is not allowing you to call 'https://www.google.com/recaptcha/api/siteverify' from a frontend because of their CORS policy. See Mozilla's CORS guide for more information about CORS. Calls can only be initiated from a backend and not from a browser.

How to enable CORS between http://localhost:3000/ and TMDB api in ReactJS?

I'm facing error where I can't get the data from TMDB API.
Access to XMLHttpRequest at 'https://api.themoviedb.org/3' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
axios.js setup
import axios from "axios";
const instance = axios.create({
baseURL: "https://api.themoviedb.org/3",
})
export default instance;
request.js setup:
const API_KEY = "xxx";
const request = {
fetchTrending: `/trending/all/week?api_key=${API_KEY}&language=en-US`,
fetchNetflixOriginal: `/discover/tv?api_key=${API_KEY}&with_networks=213`,
}
export default request;
App.js
useEffect(() => {
//if [], run once when row load, and dont run again
console.log("rrrrsd >>> ", typeof(fetchUrl))
async function fetchData(){
const response = await axios.get(fetchUrl, {
headers:{
'Access-Control-Allow-Origin': '*',
}
}).then(function (response){
console.log('response >>>>', response.data)
}).catch(function (error){
if(error.response){
console.log('response error >>>', error.response.headers)
}
else if(error.request){
console.log('error request >>>', error.request)
}
else{
console.log('message error >>>', error.message)
}
})
}
fetchData()
},[fetchUrl])
Please help me to enable CORS between TMDB API and ReactJS localHost
use a google chrome extension like (CORS Domain) or (Allow CORS )
I face the same problem yesterday and the extension fix it

Resources