CORS errors when react gets redirected to login page - reactjs

I am getting the following error messages:
-Fetch API cannot load http://localhost:8080/oauth2/authorization/google due to access control checks
-Failed to load resource: Cross-origin redirection to https://accounts.google... denied by CORS policy: Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin
I made a Kotlin-SpringBoot API and I'm in the process of developing a front end in React-TypeScript.
I used SwaggerCodegen to import the functions to interact with my API with OpenAPI docs.
I want my users to be authenticated with google OAUTH, so I decided to use Spring Security to make all my endpoints need authentication. I did it using this class:
#Configuration
class SecurityConfig : WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http
.antMatcher("/**").authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login()
}
}
Now, the api is in port 8080 and the frontend is on 3000
So if I access localhost:8080/restricted I get prompted to login and it works as expected.
But if my frontend on localhost:3000 tries to retrieve any data from the API I thought It'd just redirect me anyways, but I get the CORS error above.
I have looked everywhere and just want to know if my approach is conceptually wrong or how I can authorize this type of redirecting (or if I even should).
Thanks for any help!

Related

Spring OAuth2 authentication with token

I have this SpringBoot app, which uses the OAuth2 login via Google. And it works just fine on it's own.
However, I'm trying to connect it with my React frontend and thus: trying to develop the exchange of tokens.
SecurityConfig
http.cors()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/oauth/**")
.authenticated()
.anyRequest()
.permitAll()
.and()
.oauth2Login();
Now, I'm obtaining the token this way:
OAuth2AuthorizedClient client = authorizedClientService.loadAuthorizedClient(authentication.getAuthorizedClientRegistrationId(), authentication.getName());
String token = client.getAccessToken().getTokenValue();
and send it to my React client.
The question is: how to receive and interpret the authorization token at SpringBoot app?
Right now it's giving me a CORS issue as soon as I attach the Authoriation header...
you have to configure the allowed CORS requests in your spring boot app or serve your react frontend from the same domain.
personally ive always done the second option, with the spring boot app serving the react bundle on some url (e.g. /static/js/).

Access to XMLHttpRequest blocked by CORS Policy in ReactJS using Axios

I'm setting up stripe connect button in my React Component using Axios. I keep getting this error after redirection
Access to XMLHttpRequest at 'https://connect.stripe.com/oauth/token' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
Thankyou.js:40 Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:87)
I get the code from the url and create a curl request using axios.Post. This is the code in my redirect URL
// Thankyou.js
export default class Thankyou extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
const code = qs.parse(this.props.location.search, {
ignoreQueryPrefix: true
}).code;
const params = {
client_id: "*******************",
client_secret: "**********************",
grant_type: "authorization_code",
code: code
};
axios
.post(
"https://connect.stripe.com/oauth/token",
// apiBaseUrl,
{ params }
)
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
console.log(code);
}
render() {
return (
<div>
<h2>Thank you for connecting with us!</h2>
</div>
);
}
}
There is nothing wrong with your code, but most likely the API endpoint the code trying to reach is not setup for JavaScript web app. CORS policy is set on the server-side and enforced primarily on the browser-side.
The best way to work around is to use Stripe's JavaScript solution such as Strip React Elements or Stripe.js.
A hacky way to get around CORS would be setting up Reverse proxy with solutions such as NGINX. For example, you can use the following nginx configuration:
server {
listen 8080;
server_name _;
location / {
proxy_pass http://your-web-app:2020/;
}
location /stripe/ {
proxy_pass https://connect.stripe.com/;
}
}
By doing so, all the API calls to Stripe.com could be through /stripe under your web app's URL. For example, calling http://yourapp/stripe/oauth/token would be same as calling https://connect.stripe.com/oauth/token
That being said, the second solution is hacky and Stripe may decide to block your reverse proxy server.
basically you need to talk to whoever is hosting this https://connect.stripe.com/oauth/token to enable CORS (Cross Origin Resource Sharing )
It is a security measure implemented by most standard browsers to stop unwanted requests to your backend
It's probably because Stripe doesn't provide JavaScript client so you either have to use your own server proxy or use something like "https://cors-anywhere.herokuapp.com/https://connect.stripe.com/oauth/token"
I hope this answer would be useful to new users:
This issue can be easily fixed by using an annotation in your spring boot rest controller class.
Something like below (also ref screenshot):
#CrossOrigin(origins = "http://localhost:4200")
Explicitly mention the react JS server URL that is causing this issue.
Now after adding above annotation (with your react JS server URL) the browser will allow the flow.
All the best.
Learn about CORS
Think about it, there is anything wrong with your axios.post request, it's successfully contacting the server. But there is one more thing to do before the server let you execute or manipulate it's files.
For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy.
So your cross-origin request and the server Cross-Origin Resource Sharing (CORS) have to match.
How do you solve it?
Depending on your server and the server side programming language your are implementing, you can configure the different parameters to handle your CORS.
For example, you can configure that the only allowed methods will be:
GET HEAD
So if someone try to axios.post to your server with a different method like POST, it will return an error like this:
Access to XMLHttpRequest at 'https://connect.stripe.com/oauth/token' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
Thankyou.js:40 Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:87)
Resources:
https://www.w3.org/TR/cors/
https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
I would suggest reading through this site: https://stripe.com/docs/recipes/elements-react
It gives specific instructions straight from stripe on using their API with react. Good luck!

Access-Control-Allow-Origin Error Only on a Single Route, Only When Deployed to GAE

I'm using google app engine to host both my frontend and my api backend. I'm getting the following errors when I'm polling the "slicingdone" route on my backend:
bootstrap e65cef5bb029055e1719:2 GET
https://playloopsbackend-217106.appspot.com/playloops/slicingdone 502
send # bootstrap e65cef5bb029055e1719:2
/videotogifs:1 Access to XMLHttpRequest at
'https://playloopsbackend-217106.appspot.com/playloops/slicingdone'
from origin 'https://playloopsfrontend.appspot.com' has been blocked
by CORS policy: No 'Access-Control-Allow-Origin' header is present on
the requested resource.
I poll the slicingdone function to figure out when trimming of a video on my backend is finished. It works locally but is presenting the above errors when deployed to gcloud.
slicingdone function on my backend looks like this(Express):
slicingdone(req, res, next) {
if(slicingIsDone == true){
res.status(200).send('true');
slicingIsDone = false;
}else{
res.status(200).send('false');
}
}
*Every other route on my backend works fine even when deployed. I have similar functions on the backend that manipulate videos using ffmpeg in different ways. I have whitelisted my frontend url on my backend, so I'm not sure why I'm getting these CORs errors. I store the video results in google cloud storage--perhaps I need to add my backend url to google cloud CORS whitelist?
Any help is much appreciated! Thank you!

Keycloak CORS issue associated with login redirect

Similar questions here and here have not helped me resolve the problem.
I am using Keycloak 4.4.0 to secure my REST service, which is implemented using Spring Boot and I am using React for the front end.
I get a CORS error when the front end (running on localhost:3000) makes an API call to localhost:8080/login and is redirected to the Keycloak login page.
The error is:
localhost/:1 Failed to load http://localhost:8080/login: Redirect from 'http://localhost:8080/login' to 'http://localhost:9080/auth/realms/hbs/protocol/openid-connect/auth?response_type=code&client_id=hbs&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Flogin&state=ab5034a9-4baa-4be3-9ec1-feefbe5f9c0b&login=true&scope=openid' 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 have added a single value of '*' to the Web Origins config section in the Keycloak client.
I have annotated my REST controller as follows:
#RestController
class MyController
{
#CrossOrigin
#GetMapping("/login")
public ResponseEntity<Foo> getFoo(Principal principal)
{
return ResponseEntity.ok(new Foo("blah"));
}
}
I have enabled Keycloak and CORS in the application properties:
keycloak.cors = true
keycloak.enabled = true
If I disable Keycloak and CORS, problem goes away.
As described here, I suspect the issue is to do with the Keycloak server not responding with any Access-Control-Allow-Origin headers despite Web Origins being correctly configured in the Keycloak admin portal. But I'm not completely sure how to confirm this.
Imagine the following json below is your Keycloak configuration:
{
"realm" : "cors",
"resource" : "cors-database-service",
"auth-server-url": "http://localhost-auth:8080/auth",
"bearer-only" : true,
"ssl-required": "external",
"enable-cors": true
}
Try adding the last line to your configuration file.
Let me know if it worked for you!
OBS: I'm facing the same issue, but I'm using Wildfly/JBOSS adapters and making this configuration inside the application server.
#EDIT:
This worked fine for me.
Try changing the "Access Type" to bearer-only inside your REST Client on Keycloak.
Also, don't forget to add the parameter {"{"Authorization" : "bearer " + $TOKEN} when sending HTTP requests from your client to your RESTful API.
For those encountering this error with spring. Just add this class to your project to allow cors:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
public class CorsConfig implements WebMvcConfigurer {
String[] origins = new String[] { "http://localhost:8081"};
#Override
public void addCorsMappings(CorsRegistry registry) {
System.out.println("TEST TEST");
registry.addMapping("/**")
.allowedOrigins("*");
// .allowedOrigins(origins);
}
}
The asterisk allows all origins, which may not be secure for productive systems. A string array can be used to specify more than one origin.

CORS request did not succeed - react

I make this API request , using axios in ReactJS
axios.post(`${API_URL}/valida_proximo`, {
id: images.map(image => image.id)
},
getAxiosConfig())
// this.setState({ images, loadingAtribuiImagens: false})
}
It works really well in Google Chrome, but on Firefox I receive an error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:5000/valida_proximo. (Reason: CORS request did not succeed).[Learn More]
What can I do?
This is my API
#blueprint.route('', methods=['POST', ])
#jwt_required()
def index():
if request.json:
id_usuarioImagem = request.json.get('id')
imagens_selecionadas =
UsuarioImagem.query.filter(UsuarioImagem.id.in_(id_usuarioImagem)).all()
if imagens_selecionadas:
for imagem_selecionada in imagens_selecionadas:
imagem_selecionada.batido=True
db.session.commit()
return 'ok', 200
return 'error', 400
CORS errors are usually associated with cross domain requests and something not configured to accept a request on the recipient side of the request. The fact that chrome is working but firefox doesn't seems rather strange.
This was a method I used:
Open Firefox browser and load the page.
Perform the operation which is throwing Cross Origin Request Security (CORS) error.
Open firebug and copy the URL which is throwing Cross Origin Request Security (CORS) error.
Load the same URL in another tab in same Firefox browser.
Once you open the URL in another tab will ask you to add the certificate.
After adding the certificate will resolve Cross Origin Request Security (CORS) error and now you will not be getting this error.
I'm not too familiar with Axios, but it looks like you're making a post request from your React to your Flask backend. If the front-end and the backend are on different ports (like your Flask seems to be on PORT 5000), then you're making a CORS request.
With CORS, depending on what you're posting, you might need to include some Access-Control headers in your Flask response object. You can do this either manually, or just pip-installing and using the 'flask-cors' package. Import the package into your app factory and use it like so (see their docuementation for more info):
from flask_cors import CORS
def create_app(test_config=None):
app = Flask(__name__, instance_relative_config=True)
CORS(app)
The request might also get 'preflighted' with an 'OPTIONS' request, also depending on the nature of your POST. More information would be helpful
This is a bug in firefox.
if you follow the link (MDN) in the error msg . you will find:
What went wrong?
The HTTP request which makes use of CORS failed because the HTTP connection failed at either the network or protocol level. The error is not directly related to CORS, but is a fundamental network error of some kind.
which i read as the connection failed and not a problem with CORS settings.
you will just have to ignore the error message until firefox gets it fixed.
The error has something to do with refreshing the page and long polling requests or service workers and polling requests.
If anyone sees this question again, I had this problem because I made a request to https://url instead of http://url

Resources