Heroku NodeJS http to https ssl को पुनर्निर्देशित किया गया


105

मेरे पास एक आवेदन है और उसके साथ नोड पर एक्सप्रेस के साथ चल रहा है, https। मैं प्रोटोकॉल की पहचान कैसे कर सकता हूं कि उसे नोड पर हर्ज़ू के साथ https पर पुनर्निर्देशित करने के लिए मजबूर किया जाए?

मेरा ऐप केवल एक साधारण http सर्वर है, यह (अभी तक) महसूस नहीं करता है कि हरको इसे https अनुरोध भेज रहा है:

/* Heroku provides the port they want you on in this environment variable (hint: it's not 80) */
app.listen(process.env.PORT || 3000);

6
हरोकू समर्थन ने मेरे उपरोक्त प्रश्न का उत्तर दिया, और मुझे यह पहले से यहां पोस्ट नहीं मिला, इसलिए मैंने सोचा कि मैं इसे सार्वजनिक रूप से पोस्ट करूंगा और ज्ञान साझा करूंगा। वे मूल अनुरोध के बारे में बहुत सी जानकारी पास करते हैं जिसमें यह अनुरोध है कि हेडर 'एक्स-' के साथ उपसर्ग करता है। यहाँ अब मैं उपयोग कर रहा हूँ (मेरी रूट परिभाषाओं के शीर्ष पर):app.get('*',function(req,res,next){ if(req.headers['x-forwarded-proto']!='https') res.redirect('https://mypreferreddomain.com'+req.url) else next() })
डेरेक ब्रेडेनस्टीनर

1
ठीक है तो मुझे लगता है कि आप इस तरह से https के लिए जाँच करें और यदि आवश्यक हो तो पुनर्निर्देशित करें। लेकिन क्या आपके डोमेन नाम प्रदाता के साथ dns स्तर पर फिर से करने का एक तरीका है। इसलिए ब्राउज़र के समाधान से पहले DNS यह पहले से ही https पर है। क्योंकि इस दृष्टिकोण के साथ यह है कि, मुझे लगता है कि मेरे ज्ञान को पुनर्निर्देशित किया गया है, कि एक बार अनुरोध http पर किया जाता है और फिर से https पर। इसलिए यदि संवेदनशील डेटा भेजा गया था, तो इसे एक बार http पर भेजा गया था। उसके बाद https। कौन सा किन्नर उद्देश्य को हरा देता है। कृपया मुझे बताएं कि क्या मैं गलत हूं।
मुहम्मद उमर

@ मुहम्मदउमर, आपका तर्क यहाँ इंगित करता है, क्या आपने कभी और खोज की है?
कारो

मैं बस नामकरण के रूप में क्लाउडफ्लेयर का उपयोग करता था जो कि nginx के रूप में काम करता है, और मुझे टॉगल बटन पर क्लिक करके ssl संस्करण पर पुनर्निर्देशित करता है। आप यह भी कर सकते हैं: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/… इसके अलावा, आमतौर पर कोई भी डेटा को तुरंत नहीं भेजता है जो वे आमतौर पर फॉर्म में लैंड करते हैं और फिर सबमिट करते हैं। तो सर्वर साइड कोड, डीएनएस सर्वर, http हेडर, जावास्क्रिप्ट पर आप https डेवलपर.
मुहम्मद उमर

जवाबों:


107

आज के अनुसार, 10 अक्टूबर 2014 , हरोकू सेडर स्टैक और एक्सप्रेसजेएस ~ 3.4.4 का उपयोग करते हुए , यहां कोड का एक कार्य समूह है।

यहां याद रखने वाली मुख्य बात यह है कि हम हरोकू में तैनात हैं। SSL समापन लोड बैलेंसर पर होता है, एन्क्रिप्टेड ट्रैफ़िक आपके नोड ऐप तक पहुंचने से पहले। यह जांचना संभव है कि क्या https का उपयोग req.headers ['x-forwarded-proto'] === 'https' के साथ अनुरोध करने के लिए किया गया था ।

हमें ऐप आदि के अंदर स्थानीय एसएसएल प्रमाण पत्र के साथ खुद को चिंता करने की आवश्यकता नहीं है क्योंकि आप अन्य वातावरणों में होस्टिंग कर सकते हैं। हालाँकि, आपको अपने स्वयं के प्रमाण पत्र, उप-डोमेन आदि का उपयोग करते हुए सबसे पहले हरकू एड-ऑन के माध्यम से एक SSL एड-ऑन प्राप्त करना चाहिए।

फिर HTTPS से HTTPS के अलावा किसी अन्य चीज़ से रीडायरेक्ट करने के लिए बस निम्नलिखित जोड़ें। यह ऊपर दिए गए स्वीकृत उत्तर के बहुत करीब है, लेकिन:

  1. यह सुनिश्चित करता है कि आप "app.use" का उपयोग करें (सभी कार्यों के लिए, सिर्फ प्राप्त नहीं)
  2. स्पष्ट रूप से एक घोषित फ़ंक्शन में ForceSsl तर्क को बढ़ाता है
  3. "App.use" के साथ '*' का उपयोग नहीं करता है - यह वास्तव में विफल रहा जब मैंने इसका परीक्षण किया।
  4. यहां, मैं केवल उत्पादन में एसएसएल चाहता हूं। (अपनी आवश्यकताओं के अनुसार बदलें)

कोड:

 var express = require('express'),
   env = process.env.NODE_ENV || 'development';

 var forceSsl = function (req, res, next) {
    if (req.headers['x-forwarded-proto'] !== 'https') {
        return res.redirect(['https://', req.get('Host'), req.url].join(''));
    }
    return next();
 };

 app.configure(function () {

    if (env === 'production') {
        app.use(forceSsl);
    }

    // other configurations etc for express go here...
}

SailsJS (0.10.x) उपयोगकर्ताओं के लिए ध्यान दें। आप बस एपीआई / नीतियों के अंदर एक नीति (enforceSsl.js) बना सकते हैं:

module.exports = function (req, res, next) {
  'use strict';
  if ((req.headers['x-forwarded-proto'] !== 'https') && (process.env.NODE_ENV === 'production')) {
    return res.redirect([
      'https://',
      req.get('Host'),
      req.url
    ].join(''));
  } else {
    next();
  }
};

फिर कॉन्फिग / पॉलिसियों से संदर्भ। जेएस के साथ-साथ कोई अन्य पॉलिसी, जैसे:

'*': ['प्रमाणित', 'लागू'


1
पाल नीति का उपयोग करने के बारे में एक नोट: जैसा कि sailsjs.org/#/documentation/congets/Polurities में कहा गया है : "डिफ़ॉल्ट नीति मैपिंग" कैस्केड "या" ट्रिकल डाउन नहीं है। "नियंत्रक के कार्यों के लिए निर्दिष्ट मैपिंग डिफ़ॉल्ट मैपिंग को ओवरराइड करेगा। " इसका मतलब यह है कि जैसे ही आपके पास विशिष्ट नियंत्रक / कार्रवाई के लिए अन्य नीतियां हैं, आपको उन नियंत्रक / कार्रवाई पर 'enforceSsl' जोड़ना सुनिश्चित करना होगा।
मैनुएल दरव्यू

2
"निम्न तालिका एक्सप्रेस 4 में अन्य छोटे लेकिन महत्वपूर्ण बदलावों को सूचीबद्ध करती है: ... app.configure () फ़ंक्शन को हटा दिया गया है। पर्यावरण का पता लगाने के लिए प्रक्रिया .env.NODE_ENV या app.get ('env') फ़ंक्शन का उपयोग करें। तदनुसार एप्लिकेशन को कॉन्फ़िगर करें। "
केविन व्हीलर

9
यह भी ध्यान दें कि res.redirectयह चूक 302 रीडायरेक्ट करने के लिए है (कम से कम व्यक्त 4.x में)। एसईओ और कैशिंग कारणों से, आप शायद इसके बजाय 301 पुनर्निर्देशित करना चाहते हैं। साथ इसी लाइन की जगहreturn res.redirect(301, ['https://', req.get('Host'), req.url].join(''));
केविन व्हीलर

6
नोट: में Express 4.x, app.configureलाइन को हटा दें और केवल आंतरिक औषधि का उपयोग करें। app.configureविरासत कोड है और अब एक्सप्रेस में शामिल नहीं है।
ऑगी गार्डनर

96

इसका उत्तर 'एक्स-फ़ॉर्वर्ड-प्रोटो' के हेडर का उपयोग करना है जिसे हरोकू आगे बढ़ाता है क्योंकि यह प्रॉक्सी चीज़ामैब है। (साइड नोट: वे कई अन्य एक्स-चर भी पास करते हैं जो काम में आ सकते हैं , उन्हें देखें )।

मेरा कोड:

/* At the top, with other redirect methods before other routes */
app.get('*',function(req,res,next){
  if(req.headers['x-forwarded-proto']!='https')
    res.redirect('https://mypreferreddomain.com'+req.url)
  else
    next() /* Continue to other routes if we're not redirecting */
})

धन्यवाद ब्रैंडन, बस उस 6 घंटे की देरी के लिए इंतजार कर रहा था जो मुझे अपने सवाल का जवाब नहीं देगा।


4
यह अन्य तरीकों से नहीं होने देंगे GET?
जेड श्मिट

1
@ ऐरॉन: यदि आप पारदर्शी रूप से एक पोस्ट-अनुरोध को पुनर्निर्देशित करते हैं, तो आप संभावित रूप से जानकारी खो देंगे। मुझे लगता है कि आपको http के लिए GET के अलावा अन्य अनुरोधों पर 400 वापस करना चाहिए।
थियोडोर्टन

3
आप && process.env.NODE_ENV === "production"अपने सशर्त में फेंक सकते हैं यदि आप केवल अपने उत्पादन वातावरण में काम करना चाहते हैं।
प्रेट्रिचुअल

307 (एक ही विधि से अनुप्रेषित) संभवतः 400 त्रुटि से बेहतर है।
बेनी चेर्नियाव्स्की-पास्किन

इस उत्तर के साथ कई समस्याएँ हैं, नीचे अगला उत्तर देखें ( stackoverflow.com/a/23894573/14193 ) और इसे नीचे रेट करें।
नील

22

स्वीकार किए गए उत्तर में एक हार्डकोड डोमेन है, जो कई डोमेन (जैसे: dev-yourapp.com, test-yourapp.com, yourapp.com) पर समान कोड होने पर बहुत अच्छा नहीं है।

इसके बजाय इसका उपयोग करें:

/* Redirect http to https */
app.get('*', function(req,res,next) {
  if(req.headers['x-forwarded-proto'] != 'https' && process.env.NODE_ENV === 'production')
    res.redirect('https://'+req.hostname+req.url)
  else
    next() /* Continue to other routes if we're not redirecting */
});

https://blog.mako.ai/2016/03/30/redirect-http-to-https-on-heroku-and-node-generally/


अच्छा काम करता है। मैं duno क्यों मैं सिर्फ बदलने के लिए किया था req.hostnameके साथ req.headers.hostहो सकता है एक्सप्रेस संस्करण मैं 4.2 में हूँ
जेरेमी Piednoel

16

मैंने एक छोटा नोड मॉड्यूल लिखा है जो एक्सप्रेस परियोजनाओं पर एसएसएल लागू करता है। यह मानक स्थितियों में और रिवर्स प्रॉक्सिस (हर्को, नोडजित्सु, आदि) के मामले में दोनों काम करता है।

https://github.com/florianheinemann/express-sslify


6

यदि आप x-forwarded-protoअपने लोकलहोस्ट पर हेडर का परीक्षण करना चाहते हैं , तो आप एक nhost फ़ाइल का उपयोग करने के लिए nginx का उपयोग कर सकते हैं जो आपके नोड ऐप के सभी अनुरोधों को सम्‍मिलित करता है। आपकी nginx vhost config फाइल इस तरह दिख सकती है

nginx

server {
  listen 80;
  listen 443;

  server_name dummy.com;

  ssl on;
  ssl_certificate     /absolute/path/to/public.pem;
  ssl_certificate_key /absolute/path/to/private.pem;

  access_log /var/log/nginx/dummy-access.log;
  error_log /var/log/nginx/dummy-error.log debug;

  # node
  location / {
    proxy_pass http://127.0.0.1:3000/;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

यहाँ महत्वपूर्ण बिट्स हैं कि आप सभी अनुरोधों को लोकलहोस्ट पोर्ट ३००० पर भेज रहे हैं (यह वह जगह है जहाँ आपका नोड ऐप चल रहा है) और आप हेडर का एक गुच्छा सेट कर रहे हैं जिसमें शामिल हैं X-Forwarded-Proto

फिर अपने ऐप में हमेशा की तरह उस हेडर का पता लगाएं

एक्सप्रेस

var app = express()
  .use(function (req, res, next) {
    if (req.header('x-forwarded-proto') == 'http') {
      res.redirect(301, 'https://' + 'dummy.com' + req.url)
      return
    }
    next()
  })

कोआ

var app = koa()
app.use(function* (next) {
  if (this.request.headers['x-forwarded-proto'] == 'http') {
    this.response.redirect('https://' + 'dummy.com' + this.request.url)
    return
  }
  yield next
})

मेजबान

अंत में आपको इस लाइन को अपनी hostsफाइल में जोड़ना है

127.0.0.1 dummy.com

6

आपको हरोकू-एसएसएल-रीडायरेक्ट पर एक नज़र रखना चाहिए । यह एक सम्मोहन की तरह काम करता है!

var sslRedirect = require('heroku-ssl-redirect');
var express = require('express');
var app = express();

// enable ssl redirect
app.use(sslRedirect());

app.get('/', function(req, res){
  res.send('hello world');
});

app.listen(3000);

4

यदि आप हरकोलू के साथ संयोजन में cloudflare.com का उपयोग CDN के रूप में कर रहे हैं, तो आप इसके लिए आसानी से Cloudflare के भीतर स्वचालित ssl पुनर्निर्देशन को सक्षम कर सकते हैं:

  1. लॉगिन करें और अपने डैशबोर्ड पर जाएं

  2. पेज नियम चुनें

    पेज नियम चुनें

  3. अपना डोमेन जोड़ें, जैसे www.example.com और स्विच हमेशा https का उपयोग करें स्विच हमेशा https का उपयोग करें

3

लूपबैक उपयोगकर्ता मिडलवेयर के रूप में आर्कसेलडन उत्तर के थोड़े अनुकूलित संस्करण का उपयोग कर सकते हैं:

सर्वर / मिडलवेयर / forcessl.js

module.exports = function() {  
  return function forceSSL(req, res, next) {
    var FORCE_HTTPS = process.env.FORCE_HTTPS || false;
      if (req.headers['x-forwarded-proto'] !== 'https' && FORCE_HTTPS) {
        return res.redirect(['https://', req.get('Host'), req.url].join(''));
      }
      next();
    };
 };

सर्वर / server.js

var forceSSL = require('./middleware/forcessl.js');
app.use(forceSSL());

2

यह ऐसा करने के लिए एक अधिक एक्सप्रेस विशिष्ट तरीका है।

app.enable('trust proxy');
app.use('*', (req, res, next) => {
  if (req.secure) {
    return next();
  }
  res.redirect(`https://${req.hostname}${req.url}`);
});

0
app.all('*',function(req,res,next){
  if(req.headers['x-forwarded-proto']!='https') {
    res.redirect(`https://${req.get('host')}`+req.url);
  } else {
    next(); /* Continue to other routes if we're not redirecting */
  }
});

0

App.use और गतिशील यूआरएल के साथ। दोनों स्थानीय और मेरे लिए हरोकू पर काम करता है

app.use(function (req, res, next) {
  if (req.header('x-forwarded-proto') === 'http') {
    res.redirect(301, 'https://' + req.hostname + req.url);
    return
  }
  next()
});

-1

एक्स-फॉरवर्डेड-प्रोटो हेडर में प्रोटोकॉल की जांच करना हर्को पर ठीक काम करता है, जैसे डेरेक ने बताया है। जो इसके लायक है, उसके लिए यहां एक्सप्रेस मिडलवेयर का उपयोग किया गया है जिसका मैं उपयोग करता हूं और इसके अनुरूप परीक्षण करता हूं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.