I have a server with docker, with a web server within a docker running behind Cloudflare. Nginx reverse proxies the subdomain to the correct port on the server, where the Node.js web server is. Everything works fine, but when I try to authenticate with Twitch, it takes me back to the web server’s login page again. It was working fine prior to proxying the subdomain behind Cloudflare. When I check the Nginx access logs, it shows that it is in fact getting the GET requests.
Access Log:
"GET /auth/twitch HTTP/2.0" 302 0 "https://<subdomain>/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53"
"GET /auth/twitch/callback?code=<callback code> HTTP/2.0" 302 46 "https://id.twitch.tv/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53"
"GET / HTTP/2.0" 304 0 "https://id.twitch.tv/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53"
I read on other forum posts that it should be an Nginx/Webserver issue, but why is this only happening when I proxy the site behind Cloudflare?
I tried changing Page Rules/WAF on Cloudflare but it didn’t help- but maybe I was doing it wrong? Also, Bot Fight Mode isn’t enabled on Cloudflare.
(I am somewhat new to DNS/Cloudflare/Reverse Proxy issues, so please bear with me)
Seems like it’s your code located at /auth/twitch/callback that isn’t do what you expect it to do.
It doesn’t seem like it’s a Nginx issue or a cloudflare issue. But a “your code” issue.
Since these are brownser steps cloudflare would block the browser the user is using which is isn’t
And you can see the cloudflare is not blocking the request getting to nginx.
You can see that nginx is getting the request.
So whatever is processing the request is not doing what it’s supposed to do and is redirecting to / after failing to process the ?code
This is how it determines if the player should see the auth or index page. I’m thinking it has to do with Cloudflare because the site works fine when it is not set to proxied, and is set to DNS only on Cloudflare. Or, how the callback/code is affected when the site is proxied somehow.
//set route to start OAuth link, this is where you define scopes to request
app.get('/auth/twitch', passport.authenticate('twitch', { scope: 'user_read' }));
//set route for OAuth redirect
app.get('/auth/twitch/callback', passport.authenticate('twitch', { successRedirect: '/', failureRedirect: '/' }));
//detect authentication and serve game page
app.get('/', function (req, res) {
//successfully authenticated
if (req.session && req.session.passport && req.session.passport.user) {
res.sendFile('index.html', { root: 'client/html' });
}
//request authentication
else {
res.sendFile('auth.html', { root: 'client/html' });
};
});
// for nginx/nrgok
app.set('trust proxy', 1) // trust first proxy
added before this line.
I tend to run something similar to this (click thru for full code snippet/session setup)
You can also debug/determine if it’s this by logging sessionID’s and see if the sessionID is constantly changing rather than “sticking” like it should.
Thats expected since it was forwarded from cloudflare?!
if you are getting this to look up for a “trust proxy” hard coded value, DON’T since Cloudflare IP’s will change. Leaving your code not working.
So trust proxy with a boolean true is preferred. But I don’t proxy behind cloudflare. So there might be sone cloudflare specific instructions for node/express session
When setting to true, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto otherwise it may be possible for the client to provide any value.
as the express notes say to remove those headers. (Which can be done in nginx)
or you’ll need to dig out for what works well when behind a double proxy and determine if the issue is being double proxied or a SSL Schnanigan
Since you might find the problem is
Browser → HTTPS To cloudlfare → cloudflare internal to https nginx → nginx proxy non ssl to node
Where
Browser → HTTPS To cloudlfare → cloudflare internal to non http nginx → nginx proxy non ssl to node
Which seems unlikely.
Also I explicity set these headers in my nginx config:
So I can confirm that the left-most entry in the X-Forwarded-For header is the client IP, which means trust proxy = true should work, but it doesn’t seem to be. Could this narrow it down to an SSL issue?