Cors blocking me from GET-ing my server endpoint and redirecting - redirect

I'm trying to build an Oauth2 flow. Cors keeps blocking my GET request to my own server.
localhost:3000 is the browser.
localhost:3001 is the server.
I have cors setup in NestJS below and it works for every other non-redirecting endpoint:
// main.ts
import { corsConfig } from '#common/config/index';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors({
origin: [
/^https?:\/\/localhost:3000/,
],
methods: ['GET', 'POST'],
credentials: true,
});
await app.listen(process.env.PORT || 3001);
}
bootstrap();
When requesting to my server endpoint... these are the request.headers
{
"host": "localhost:3001",
"connection": "keep-alive",
"sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"100\"",
"accept": "application/json, text/plain, */*",
"sec-ch-ua-mobile": "?0",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) SomeStuff",
"sec-ch-ua-platform": "\"Windows\"",
"origin": "http://localhost:3000",
"sec-fetch-site": "same-site",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"referer": "http://localhost:3000/",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9,fr;q=0.8,es;q=0.7,de;q=0.6",
"cookie": "Authentication=someStuff"
}
When responding from my server, these are the response.headers
{
"cross-origin-opener-policy": "same-origin",
"cross-origin-resource-policy": "same-origin",
"x-dns-prefetch-control": "off",
"expect-ct": "max-age=0",
"x-frame-options": "SAMEORIGIN",
"strict-transport-security": "max-age=15552000; includeSubDomains",
"x-download-options": "noopen",
"x-content-type-options": "nosniff",
"origin-agent-cluster": "?1",
"x-permitted-cross-domain-policies": "none",
"referrer-policy": "no-referrer",
"x-xss-protection": "0",
"access-control-allow-origin": "http://localhost:3000",
"vary": "Origin",
"access-control-allow-credentials": "true",
"x-ratelimit-limit": "30",
"x-ratelimit-remaining": "28",
"x-ratelimit-reset": "60"
}
And this is the Cors error in my browser console
Access to XMLHttpRequest at 'https://example.com/' (redirected from
'http://localhost:3001/test') from origin 'http://localhost:3000'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource.
What do I need to change to allow a GET request to be redirected in the browser? Or is this not possible and it requires simply visiting the site with window.location?

I know this is not the ideal solution, but for my personal projects in a local environment, I used the "Moesif Origin & CORS Changer" browser extension to combat this annoying issue.
Google Chrome: https://chrome.google.com/webstore/detail/moesif-origin-cors-change/digfbfaphojjndkpccljibejjbppifbc
Firefox: https://addons.mozilla.org/en-US/firefox/addon/moesif-origin-cors-changer1/

Related

In my deno fresh app, I can't get form inputs and send them to an async function

This is a deno "fresh" framework app and I have a island that allows the admin to create new users. Obviously this is a security vulnerability but this is just a testing proof of concept and I'm just trying to get a "fresh" app to send form data to the backend. This is my Creator island.
islands/Creator.tsx
// import { useState } from "preact/hooks";
import { useState, useEffect } from "preact/hooks";
import { Handlers, PageProps } from "$fresh/server.ts";
import UserDb from "../database.ts";
interface CreatorProps {
email: string,
key: string
}
export default function Creator(props: CreatorProps) {
const handleSubmit = (event) => {
event.preventDefault();
const emailInput = event.target.email;
const ageInput = event.target.key;
console.log(emailInput.value);
console.log(ageInput.value);
createNewUser(emailInput.value, ageInput.value)
};
async function createNewUser(email, key) {
console.log(email);
console.log(key);
const headers = new Headers({
'Content-Type': 'text/plain'
});
const opts = {
method: 'POST',
headers: headers,
body: JSON.stringify({
email: email,
key: key,
})
}
const rawPosts = await fetch('http://localhost:8000/api/createUser', opts);
console.log(rawPosts);
}
return (
<div>
<form onsubmit={handleSubmit}>
<h1 class="text rounded-lg p-4 my-8"> Search </h1>
<input class="center rounded-lg p-4 my-8" type="text" name="email" />
<input class="center rounded-lg p-4 my-8" type="text" name="key" />
<br />
<button
class="px-5 py-2.5 text-sm font-medium bg-blue-600 rounded-md shadow disabled:(bg-gray-800 border border-blue-600 opacity-50 cursor-not-allowed)"
type="submit">Submit
</button>
</form>
<br />
{/* <ul>
{results.map((name) => <li key={name}>{name}</li>)}
</ul> */}
</div>
);
};
And when I typed uiui and rrgg in the email and key fields and hit enter, I got this error in my terminal:
Watcher File change detected! Restarting!
Listening on http://localhost:8000/
NOTICE: relation "users" already exists, skipping
Request {
bodyUsed: false,
headers: Headers {
accept: "*/*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9",
connection: "keep-alive",
"content-length": "29",
"content-type": "text/plain",
host: "localhost:8000",
origin: "http://localhost:8000",
referer: "http://localhost:8000/create",
"sec-ch-ua": '"Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"macOS"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0...."
},
method: "POST",
redirect: "follow",
url: "http://localhost:8000/api/createUser"
}
Request {
bodyUsed: false,
headers: Headers {
accept: "*/*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9",
connection: "keep-alive",
"content-length": "29",
"content-type": "text/plain",
host: "localhost:8000",
origin: "http://localhost:8000",
referer: "http://localhost:8000/create",
"sec-ch-ua": '"Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"macOS"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0...."
},
method: "POST",
redirect: "follow",
url: "http://localhost:8000/api/createUser"
}
Request {
bodyUsed: false,
headers: Headers {
accept: "*/*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9",
connection: "keep-alive",
"content-length": "29",
"content-type": "text/plain",
host: "localhost:8000",
origin: "http://localhost:8000",
referer: "http://localhost:8000/create",
"sec-ch-ua": '"Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"macOS"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0...."
},
method: "POST",
redirect: "follow",
url: "http://localhost:8000/api/createUser"
}
Request {
bodyUsed: false,
headers: Headers {
accept: "*/*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9",
connection: "keep-alive",
"content-length": "29",
"content-type": "text/plain",
host: "localhost:8000",
origin: "http://localhost:8000",
referer: "http://localhost:8000/create",
"sec-ch-ua": '"Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"macOS"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0...."
},
method: "POST",
redirect: "follow",
url: "http://localhost:8000/api/createUser"
}
Request {
bodyUsed: false,
headers: Headers {
accept: "*/*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9",
connection: "keep-alive",
"content-length": "29",
"content-type": "text/plain",
host: "localhost:8000",
origin: "http://localhost:8000",
referer: "http://localhost:8000/create",
"sec-ch-ua": '"Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"macOS"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0...."
},
method: "POST",
redirect: "follow",
url: "http://localhost:8000/api/createUser"
}
Notice email and key aren't even logging on the server side, and the function appears to be running several times
And I got this in my web console:
So why are email and key being read and logged just fine in handleSubmit but not in createNewUser()?
You need to create an api route.
/routes/api/createNewUser.ts
import { HandlerContext } from "$fresh/server.ts";
export const handler = async (_req: Request, _ctx: HandlerContext): Response => {
if(_req.method === 'POST') {
const body = await _req.json();
const {email, key} = body;
console.log('email', email);
console.log('key', key);
/* your logic to use email & key to create user here */
return new Response(JSON.stringify({
message: 'User created successfully.'
}), {
status: 200,
headers: {
'Content-Type': 'application/json'
}
});
}
}

I have a problem setting up a RESTAPI call in Azure Data Factory

I am trying to create a POST to an REST-API but I get this output (Caught by an Logic Apps HTTP grab):
{
"headers": {
! "Connection": "Keep-Alive",
"Accept": "application/json",
"Accept-Encoding": "gzip,deflate",
! "Host": "prod-187.westeurope.logic.azure.com:443",
"User-Agent": "azure-data-factory/2.0",
"Content-Length": "55",
! "Content-Type": "application/json",
"Content-Encoding": "UTF-8"
},
"body": {
"$content-encoding": "UTF-8",
"$content-type": "application/json",
"$content": "eyJuYW1lIjoiSmVzcGVyIEIuIEhhbnNlbiIsInNhbGFyeSI6IjEyMzQ1IiwiYWdlIjoiMzQifQ=="
}
}
I would have expected this:
{
"headers": {
"Accept": "application/json",
"Accept-Encoding": "deflate,gzip",
"Host": "prod-187.westeurope.logic.azure.com",
"User-Agent": "Mozilla/5.0,(Windows NT 10.0; Win64; x64),AppleWebKit/537.36,(KHTML, like Gecko),Chrome/103.0.5060.134,Safari/537.36,Edg/103.0.1264.71",
"X-Real-IP": "212.237.135.241",
"Content-Length": "42",
"Content-Type": "application/json"
},
"body": {
"name": "Jesper B. Hansen",
"salary": "12345",
"age": "34"
}
}
Why is the output scrambled?
I tried using a REST Service on a sink, and also tried it with an externalCall no real difference...
I must say, I am new at ADF, but I hope you have some good help for me.

Oauth2-Proxy do not pass X-Auth-Request-Groups header

I'm using Azure B2C for authenticate my users. For authentication piece I have oauth2-proxy running in kubernetes cluster. Oauth2-Proxy is running behind ingress-nginx and it's passing most of required headers but I do not get X-Auth-Request-Groups header in my upstream service that is behind oauth2-proxy.
Here is my token that I get from B2C:
{
"typ": "JWT",
"alg": "RS256",
"kid": "kid_value"
}.{
"exp": 1604420825,
"nbf": 1604417225,
"ver": "1.0",
"iss": "iss_value",
"sub": "sub_value",
"aud": "aud_value",
"acr": "acr_name",
"nonce": "defaultNonce",
"iat": 1604417225,
"auth_time": 1604417225,
"groups": [
"group1"
],
"identityProviders": [
"email.com"
],
"firstname": "First Name",
"surname": "Last Name",
"idp": "IDP_VALUE",
"email": "username#email.com",
"preferred_username": "User Name"
}.[Signature]
And here are headers that I get in my upstream service after successful authentication:
{
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
Accept-Encoding: "gzip, deflate, br",
Accept-Language: "en-US,en;q=0.9",
Content-Length: "0",
Cookie: "COOKIE",
Sec-Fetch-Dest: "document",
Sec-Fetch-Mode: "navigate",
Sec-Fetch-Site: "none",
Sec-Fetch-User: "?1",
Upgrade-Insecure-Requests: "1",
User-Agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
X-Auth-Request-Access-Token: "ACCESS_TOKEN",
X-Auth-Request-Email: "username#email.com",
X-Auth-Request-Preferred-Username: "User Name",
X-Auth-Request-User: "UserID",
X-B3-Parentspanid: "Parentspanid",
X-B3-Sampled: "0",
X-B3-Spanid: "Spanid",
X-B3-Traceid: "Traceid",
X-Envoy-Attempt-Count: "1",
X-Forwarded-Client-Cert: "CEERT",
X-Forwarded-For: "Forwarded-For",
X-Forwarded-Host: "Forwarded-Host",
X-Forwarded-Port: "443",
X-Forwarded-Proto: "https",
X-Real-Ip: "Real-Ip",
X-Request-Id: "Request-Id",
X-Scheme: "https"
}
all X-Auth-Request-* headers are coming but not the one with Groups. I'm using docker image quay.io/oauth2-proxy/oauth2-proxy:v6.1.1 and I saw in config https://oauth2-proxy.github.io/oauth2-proxy/configuration option "--oidc-groups-claim" but when I try to use it container won't start because this option isn't available in this version.
Any ideas what I'm missing?
It seems that the problem is image that I'm using quay.io/oauth2-proxy/oauth2-proxy:v6.1.1, when I built own image from latest master (3rd of November 2020) everything seems to be working fine and X-Auth-Request-Groups header is passed to upstream service.

Google Apps Script doesn't recognize "Host" header in HTTP POST request?

I'm trying to query ArcGIS Rest API from Google Apps script. Building the request in Postman works perfectly fine, but when I get the code into apps script, I'm having trouble that I cant seem to figure out. Here's the code:
function callEsri () {
var url = "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0/query"
var params =
{
"async": true,
"crossDomain": true,
"url": "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0/query",
"method": "POST",
"headers": {
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "PostmanRuntime/7.20.1",
"Accept": "*/*",
"Cache-Control": "no-cache",
"Postman-Token": "[TOKEN]",
"Host": "services3.arcgis.com",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "125",
"Connection": "keep-alive",
"cache-control": "no-cache"
},
"data": {
"f": "json",
"where": "CITY_JUR LIKE '%Los Angeles%'",
"outSr": "4326",
"outFields": "TRL_NAME,ELEV_FT,CITY_JUR,PARK_NAME,FID"
}
}
var response = UrlFetchApp.fetch(url, params);
var json = response.getContentText();
var data = JSON.parse(json);
Logger.log(data);
}
The Error I am getting is: Execution failed: Attribute provided with invalid value: Header:Host (line 28, file "Code")
Any reason why Google is not recognizing this and is there a way to fix this? Any help/advice is greatly appreciated.
As #TheMaster has already noted in the comments. You are already specifying the Host in the url.
Also you can take a look at the official documentation of URLFetchApp.
And in case you want more information in the head here you have the mozilla documentation on that header and also the RFC specifying the Host header.

Wiremock CORS not working

I've been used wiremock effectively for some time now, and I wanted to enable CORS access to the mocked APIs.
I've tried setting Access-Control-Allow-Origin: * and other headers in the response header, both to no avail.
Here's an example of a mapping that I have:
{
"request": {
"method": "POST",
"urlPattern": "/api/v2/general/login[\\/\\&\\?]*",
"bodyPatterns": [{
"equalToJson": "{\"password\":\"password\",\"username\":\"john#cougar.com\"} ",
"jsonCompareMode": "LENIENT",
"ignoreArrayOrder" : true,
"ignoreExtraElements" : true
}]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json",
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Methods" : "*",
"Access-Control-Allow-Headers": "Accept, Content-Type, Content-Encoding, Server, Transfer-Encoding",
"X-Content-Type-Options" : "nosniff",
"x-frame-options" : "DENY",
"x-xss-protection" : "1; mode=block"
},
"bodyFileName": "/login_response_johncougar.json"
}
}
What am I doing wrong here that's causing CORS to not work?
Thanks in advance.
I have just managed to fix this issue. Actually solution was here already Adding headers to Jetty in Wiremock.
Because your browser sends a CORS preflight request before making any actual request, you will need to set up your wiremock to stub the OPTIONS request and send back headers.
For example,
Access-Control-Allow-Origin = "*",
Access-Control-Allow-Headers: "content-type",
Access-Control-Allow-Methods = "POST, GET".
Access-Control-Allow-Headers's value has to be the same values the Access-Control-Request-Headers header contained Request header field Access-Control-Allow-Headers is not allowed by itself in preflight response.
All your responses have to send back header "Access-Control-Allow-Origin": "*" as well.
Here is a sample and this works
{
"request":
{
"urlPattern": "/country/([a-z]*)",
"method": "GET"
},
"response":
{
"status": 200,
"headers":
{
"Content-Type" : "application/json",
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Methods" : "*",
"Access-Control-Allow-Headers": "Accept, Content-Type, Content-Encoding, Server, Transfer-Encoding",
"X-Content-Type-Options" : "nosniff",
"x-frame-options" : "DENY",
"x-xss-protection" : "1; mode=block"
},
"body": "{ \"statusCode\" : \"S1000\", \"statusDescription\" : \"Success\", \"content\" : [ { \"id\" : \"1111\", \"name\" : \"aaaa\"}, { \"id\" : \"2222\", \"name\" : \"asd\" } ] }"
}
}
Use this as it is, wiremock is peculiar when it comes to spacing, here i have used a single space instead of tab, hope it helps.
I had the same problem. After a long time search without finding the solution I started to play with the groovy file and finally I found the solution.
You just need to add each header in header() method. this will solve the problem. So your sample groovy contract will be like this:
{
"request": {
"method": "POST",
"urlPattern": "/api/v2/general/login[\\/\\&\\?]*",
"bodyPatterns": [{
"equalToJson": "{\"password\":\"password\",\"username\":\"john#cougar.com\"} ",
"jsonCompareMode": "LENIENT",
"ignoreArrayOrder": true,
"ignoreExtraElements": true
}]
},
"response": {
"status": 200,
"headers": {
header("Content-Type": "application/json"),
header("Access-Control-Allow-Origin": "*"),
header("Access-Control-Allow-Methods": "*"),
header("Access-Control-Allow-Headers": "Accept, Content-Type, Content-Encoding, Server, Transfer-Encoding"),
header("X-Content-Type-Options": "nosniff"),
header("x-frame-options": "DENY"),
header("x-xss-protection": "1; mode=block")
},
"bodyFileName": "/login_response_johncougar.json"
}
}
I hope it will solve your problem (Actually it will be useful if you use groovy contracts).
You can disable cors by adding --enable-stub-cors flag
Standalone example :
java -jar wiremock-jre8-standalone-2.31.0.jar --port 8081 --enable-stub-cors
Docker example :
docker run -it --rm -p 8081:8080 --name wiremock-yadoms -v $PWD:/home/wiremock wiremock/wiremock --enable-stub-cors
For Angular developers:
first Install wiremock with following command:
npm install wiremock
Then:
"scripts": {
"ng": "ng",
"start": "ng serve",
"wiremock": "wiremock --root-dir ./wiremock --port 8080 --enable-stub-cors true --enable-browser-proxying",
...
}