I need to change Host request header property in my POST request. Is there a way to do so?
I already tried to:
redbird({
port: 8001
xfwd: 'https://final-url.com',
secure: false,
ssl: {
port: parseInt(port),
key: path.resolve(__dirname, 'dev-key.pem'),
cert: path.resolve(__dirname, 'dev-cert.pem')
}
});
xfwd: false is showing my localhost and this one does not work (probably read as true). I'd like to add property
header: { Host: "https://final-url.com" }
Related
I'm trying to setup a proxy to Contentful Delivery SDK to intercept the response and add relevant data. For development purposes, the proxy is still running locally. This is the configuration I'm using right now:
const client = createClient({
space: SPACE_ID,
accessToken: ACCESS_TOKEN,
host: CDN_URL,
environment: ENVIRONMENT,
basePath: 'api',
retryOnError: false,
proxy: {
host: 'localhost',
port: 8080,
auth: {
username: 'username',
password: 'password',
},
},
});
For some reason, this client keeps ignoring the proxy settings, making the request directly to Contentful CDN. I tried removing the host field from the configuration, but it didn't change the outcome. I also tried using the httpsAgent configuration with HttpsProxyAgent instead of the proxy one, but also didn't work.
Versions:
"contentful": "^7.11.3"
"react": "^16.13.1"
Firstly, the proxy configuration cannot be used client-side. It's unclear if that is your use case here.
There is a known bug here. Either try installing a newer version of Axios, which is the lib that the contentful SDK uses. Or use a proxyAgent:
const HttpProxyAgent = require("http-proxy-agent");
const httpAgent = new HttpProxyAgent({host: "proxyhost", port: "proxyport", auth: "username:password"})
Now just pass the agent into the create client method:
const client = createClient({
....
httpAgent: httpAgent,
....
});
Express-Session is working in development environment, as it sets the "connect.sid" cookie in my browser. However, in production it's not storing the cookie, and instead of using the same session - it creates a new one every time. I believe that the issue would be fixed if I can somehow save third party cookies, as my app was deployed using Heroku. Lastly, I have also used express-cors to avoid the CORS issue (don't know if this has anything to do with the cookie issue). I have set {credentials: true} in cors, {withCredentials: true} in Axios, as well.
Heroku uses reverse proxy. It offers https endpoints but then forwards unencrypted traffic to the website.
Try something like
app.enable('trust proxy')
And check out
https://expressjs.com/en/guide/behind-proxies.html
Issue Solved! -> Add sameSite: 'none'
Full Cookie config (express-session) for production:
cookie: {
httpOnly: true,
secure: true,
maxAge: 1000 * 60 * 60 * 48,
sameSite: 'none'
}
Adding a "name" attribute to the session config worked for me:
{
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
proxy: true, // Required for Heroku & Digital Ocean (regarding X-Forwarded-For)
name: 'MyCoolWebAppCookieName', // This needs to be unique per-host.
cookie: {
secure: true, // required for cookies to work on HTTPS
httpOnly: false,
sameSite: 'none'
}
}
I have built a Svelte application using SvelteKit that uses Cognito for authentication. I used the following site: Cognito authentication for your SvelteKit app guide me in setting this up. The app and connection to Cognito works well when running in local development via npm run dev, however, when running in production on an EC2 server via npm run build and pm2 start /build/index.js it sets the redirect_uri portion of the Cognito URI to http://localhost:3000. I can't figure out how to get it to set the redirect to my actual domain.
Here are some relevant code snippets on how it is currently set up on EC2:
/etc/nginx/sites-available/domain.conf
server {
server_name example.com;
location / {
root /var/www/html/build;
proxy_pass http://localhost:3000;
}
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
svelte.config.js
import node from '#sveltejs/adapter-node';
/** #type {import('#sveltejs/kit').Config} */
const config = {
kit: {
target: '#svelte',
adapter: node({
out: 'build',
precompress: false,
env: {
host: 'example.com',
port: '443'
}
})
}
};
export default config;
/src/lib/auth.js
import { SvelteKitAuth, Providers } from 'sk-auth';
const DOMAIN = 'myapi.auth.us-east-1.amazoncognito.com';
const config = {
accessTokenUrl: `https://${DOMAIN}/oauth2/token`,
profileUrl: `https://${DOMAIN}/oauth2/userInfo`,
authorizationUrl: `https://${DOMAIN}/oauth2/authorize`,
redirect: 'https://example.com',
clientId: myAWSclientID,
clientSecret: myAWSclientSecret,
scope: ['openid', 'email'],
id: 'cognito',
contentType: 'application/x-www-form-urlencoded'
};
const oauthProvider = new Providers.OAuth2Provider(config);
export const appAuth = new SvelteKitAuth({
providers: [oauthProvider]
});
Expected URL when going to Cognito
https://myapi.auth.us-east-1.amazoncognito.com/login?state=cmVkaXJlY3Q9Lw%3D%3D&nonce=699&response_type=code&client_id=myAWSclientID&scope=openid+email&redirect_uri=https%3A%2F%2Fexample.com%2Fapi%2Fauth%2Fcallback%2Fcognito%2F
Actual URL when going to Cognito
https://myapi.auth.us-east-1.amazoncognito.com/login?state=cmVkaXJlY3Q9Lw%3D%3D&nonce=699&response_type=code&client_id=myAWSclientID&scope=openid+email&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fcallback%2Fcognito%2F
As you can see, it is attempting to set the redirect_uri to http://localhost:3000 instead of the expected https://example.com. I'm pretty sure that there is some setting somewhere to allow it to set the correct redirect_uri when going to Cognito - any ideas or suggestions would be appreciated!
From what I can tell looking at the sk-auth module source code, redirect_uri doesn't appear to be a valid config option. Try setting the host config option in the global SkAuth constructor instead:
const config = {
accessTokenUrl: `https://${DOMAIN}/oauth2/token`,
profileUrl: `https://${DOMAIN}/oauth2/userInfo`,
authorizationUrl: `https://${DOMAIN}/oauth2/authorize`,
// redirect_uri: 'https://example.com',
clientId: myAWSclientID,
clientSecret: myAWSclientSecret,
scope: ['openid', 'email'],
id: 'cognito',
contentType: 'application/x-www-form-urlencoded'
};
.
.
export const appAuth = new SvelteKitAuth({
providers: [oauthProvider],
host: 'https://example.com',
});
After further browsing the source, you can also set the redirect option provided by the AuthCallbacks interface on the provider configuration:
const config = {
accessTokenUrl: `https://${DOMAIN}/oauth2/token`,
profileUrl: `https://${DOMAIN}/oauth2/userInfo`,
authorizationUrl: `https://${DOMAIN}/oauth2/authorize`,
// redirect_uri: 'https://example.com',
redirect: 'https://example.com',
clientId: myAWSclientID,
clientSecret: myAWSclientSecret,
scope: ['openid', 'email'],
id: 'cognito',
contentType: 'application/x-www-form-urlencoded'
};
which, incidentally, is what the author uses in the tutorial you referred to.
I have an express-stormpath application that uses Stormpath ID Site. It has this configuration:
app.use(stormpath.init(app, {
web: {
idSite: {
enabled: true,
uri: '/idSiteResult',
nextUri: '/'
},
login: {
enabled: true,
uri: config.login
},
logout: {
enabled: true,
uri: config.logout
},
me: {
expand: {
customData: true,
groups: true
}
}
}
}));
Login works fine, but logout is giving me trouble.
First, I tried logging out with the stormpath-sdk-angularjs built-in endSession()
$auth.endSession();
But I was still logged in.
Digging into express-stormpath, it looks like logout POST requires Accept type text/html for id-site logout. In stormpath-sdk-angularjs, it looks like endSession POST uses application/json.
So I tried logging out with $http.post
$http.post('/logout', null, {
headers: {
'Accept': 'text/html'
}
});
But I get this error:
XMLHttpRequest cannot load https://api.stormpath.com/sso/logout?jwtRequest=[...]. Redirect from 'https://api.stormpath.com/sso/logout?jwtRequest=[...]' to 'http://localhost:9000/idSiteResult?jwtResponse=[...]' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access.
How do I log out of Stormpath ID Site?
I work at Stormpath. ID Site requires that you actually redirect the end user to ID Site. I'm not sure why endSession() isn't working, but I'll reach out to our JS team to see if there might be a bug there.
In the meantime, you can use this code (or the equivalent in Angular-specific primitives) to accomplish a logout:
var form = document.createElement('form');
form.method = "POST";
form.action = "/logout";
form.submit();
This looks like a CORS issue. I believe you need to add at least;
Access-Control-Allow-Origin: https://api.stormpath.com
To the response headers from your server.
I am having issues with making an ExtJS AJAX request to the Nodejs server between two different domains within our network and will appreciate any help. Response fails when attempting from both http and https from ExtJS client side but a Curl from my local via http returns 200 OK with proper data. We are working with content type application/json.
ExtJS onReady function has enabled CORS:
Ext.onReady(function () {
Ext.Ajax.cors = true;
Ext.Ajax.useDefaultXhrHeader = false;
... (code removed)
})
A test from my ExtJS client side on a known working URL that will properly create the ExtJS datastore (brings back 200 OK):
Ext.create('Ext.data.Store', {
id : 'countryStore',
model : 'country',
autoLoad : true,
autoDestroy: true,
proxy: {
type: 'rest',
url : 'https://restcountries.eu/rest/v1/all',
},
reader: {
type : 'json',
headers: {'Accept': 'application/json'},
totalProperty : 'total',
successProperty: 'success',
messageProperty: 'message'
}
});
However, when attempting a request to our Nodejs server via
http:
Ext.create('Ext.data.Store', {
id : 'circuits',
model : 'circuit',
autoLoad : true,
autoDestroy: true,
proxy: {
type: 'rest',
url : 'http://ourNodeJsServerDomain:5500/v3/circuits',
},
reader: {
type : 'json',
headers: {'Accept': 'application/json'},
totalProperty : 'total',
successProperty: 'success',
messageProperty: 'message'
}
});
returns the following in Chrome's console:
Mixed Content: The page at 'https://ourExtJsDevClientSide' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://ourNodeJsServerDomain:5500/v3/circuits?_dc=1430149427032&page=1&start=0&limit=50'. This request has been blocked; the content must be served over HTTPS.
Now, when attempted over https:
Firefox shows:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://ourNodeJsServerDomain:5500/v3/circuits?_dc=1430151516741&page=1&start=0&limit=50. This can be fixed by moving the resource to the same domain or enabling CORS.
and the Request Header doesn't show "application/json", is this an issue?:
Accept
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding
gzip, deflate
Accept-Language
en-US,en;q=0.5
Host
ourNodeJsServerDomain:5500
Origin
https://ourExtJsDevClientSide
Referer
https://ourExtJsDevClientSide
User-Agent
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:37.0) Gecko/20100101 Firefox/37.0
I then tried with Curl to see what the responses were to help debug
on http gives a 200 OK response but Access-Control-Allow-Origin is undefined even when we are defining it as "*":
curl http://ourNodeJsServerDomain:5500/v3circuits?_limit=1 -v
> GET /v3/circuits?_limit=1 HTTP/1.1
> User-Agent: curl/7.37.1
> Host: ourNodeJsServerDomain:5500
> Accept: */*
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Access-Control-Allow-Origin: undefined
< Access-Control-Allow-Methods: GET
< Access-Control-Allow-Headers: Content-Type
< Content-Type: application/json; charset=utf-8
< Content-Length: 1126
< ETag: W/"MlbRIlFPCV6w7+PmPoVYiA=="
< Date: Mon, 27 Apr 2015 16:24:18 GMT
< Connection: keep-alive
<
[
{ *good json data returned here* } ]
then when I attempt to Curl via https
curl https://ourNodeJsServerDomain:5500/v3/circuits?_limit=1 -v
* Server aborted the SSL handshake
* Closing connection 0
curl: (35) Server aborted the SSL handshake
We have enabled CORS on our Nodejs server:
router
.all('*', function(req, res, next){
res.setHeader('Content-Type', 'application/json');
// res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
// console.log('\n\nreq.headers.origin ===================== ' + req.headers.origin);
//I have tried allowing all * via res.SetHeader and res.header and neither is defining the Access-Control-Allow-Origin properly when curling
//res.setHeader("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Origin", "*");
// res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Methods', 'GET');
res.header('Access-Control-Allow-Headers', 'Content-Type');
I have attempted to be detailed in my thought process and I am willing to try new ways to determine how to understand and solve this.
* SOLUTION *
The issue is mixed content from the browser. Our client UI is on https (secure) whereas we were requesting http (unsecure) content from the nodejs server. We needed to allow for our nodejs server to run on https
We generated SSL certifications and implemented them onto our nodejs server.
Within the nodejs code, we enabled CORS with the CORS module and are running both http and https servers:
// enable CORS for all requests
var cors = require('cors');
app.use(cors());
// for certifications
var credentials = {
key: fs.readFileSync('our.key'),
cert: fs.readFileSync('our.crt')
};
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
httpServer.listen(port, function() {
console.log('HTTP server listening on port ' + port);
});
httpsServer.listen(httpsPort, function() {
console.log('HTTPS server listening on port ' + httpsPort);
});
There seems to be issues with both CORS and HTTPS in your server... You should try this middleware for the CORS part, and make it work when accessing the page in raw HTTP first. As far as I know, you'll have to use different ports for HTTP and HTTPS. And you will also probably need to enable CORS credentials. As I said, I think you'd better make it work in HTTP first ;)
Then, on the Ext part, as already mentioned in comments, you should probably disable default headers (or you'll have to make all of them accepted by your server; see the first comment to this answer). But you need to do that on the proxy, because apparently it replaces the global setting in Ext.Ajax.
So, something like this:
Ext.create('Ext.data.Store', {
id : 'countryStore',
model : 'country',
autoLoad : true,
autoDestroy: true,
proxy: {
type: 'rest',
url : 'https://restcountries.eu/rest/v1/all',
useDefaultXhrHeader: false, // <= HERE
reader: {
type : 'json',
headers: {'Accept': 'application/json'},
totalProperty : 'total',
successProperty: 'success',
messageProperty: 'message'
}
} // <= and notice this change
});
Probably unrelated, but note that your indendation was incorrect and hid the fact that the reader option was applied to the store itself instead of the proxy (so it was ignored).