首頁 > web前端 > js教程 > 主體

Node.js怎麼部署HTTPS

php中世界最好的语言
發布: 2018-03-19 17:04:00
原創
3419 人瀏覽過

這次帶給大家Node.js怎麼部署HTTPS,Node.js部署HTTPS的注意事項有哪些,下面就是實戰案例,一起來看一下。

隨著網路快速發展,網路資訊安全越來越受到大家重視,HTTPS 應該是近兩年各大廠商都在盡力普及的技術之一。國內大廠基本上已經全面普及了 HTTPS。

HTTPS 現況

這篇文章就跟大家介紹一下Node.js 如何部署免費HTTPS 以及簡單的部署HTTP/ 2

截止2018 年03 月13 日,由Let's Encrypt 即時統計報告顯示,在統計的6930 多萬活躍網站中,已經有5350 萬(約77%)的站點部署了HTTPS 憑證服務。

lets encrypt stats

同時Google 透明度報告- 網路上的HTTPS 加密中,統計了使用Chrome 瀏覽器,存取的網站統計中,HTTPS 使用率的成長情況:

google stats

而在今年2 月份,Chrome 團隊也宣布,將在2018 年7 月份發布的Chrome 68 中,將沒有部署HTTPS 的網站標記為"不安全"。

chrome 68 status

簡而言之,HTTPS 大勢所趨。

Node.js 部署HTTPS

早在《 從HTTP 到HTTPS - IIS 部署免費HTTPS 》一文中,我就指出了Let's Encrypt 免費憑證的優勢:

#由ISRG(Internet Security Research Group,網路安全研究小組)提供服務,免費、存取速度快,穩定等。

所以這次部署的憑證也是圍繞著 Let's Encrypt 展開。

greenlock-express

由於js 生態圈的繁華,所以想找一個現有的包是件很輕鬆的事情,greenlock-express 這個包就幫我們封裝了 Let's Enctrypt 憑證的部署,只需要引入這個套件並使用,就可以:

  1. 自動註冊Let's Encrypt 憑證

  2. 自動續訂( 80 天左右),且伺服器無需重新啟動

  3. #支援虛擬主機

並且greenlock 相關的證書生態圈十分完善,同樣有支援koa 的greenlock-koa。

安裝和使用

透過npm 安裝greenlock-express

$ npm install --save greenlock-express@2.x
登入後複製

使用起來非常簡單,這是greenlock-express 預設提供的demo:

const greenlock = require('greenlock-express')
require('greenlock-express').create({
  // 测试
  server: 'staging',
  // 联系邮箱
  email: 'john.doe@example.com',
  // 是否同意 Let's Encrypt 条款... 这必须为 true 啊,不然走不下去
  agreeTos: true,
  // 申请的域名列表,不支持通配符
  approveDomains: [ 'tasaid.com', 'www.tasaid.com' ],
  // 绑定 express app
  app: require('express')().use('/', function (req, res) {
    res.end('Hello, World!');
  })
}).listen(80, 443)
登入後複製

憑證存在~/letsencrypt

當然上面程式碼只能用於測試/開發環境,因為它並沒有申請一個有效的證書,而是產生了一個自簽名的證書(跟以前的12306 自簽證書一樣),用於在開發環境中調試。

API

greenlock-expresscreate(options) 函數參數簽名如下:

interface Options {
  /**
   * Express app
   */
  app: Express
  /*
   * 远程服务器
   * 测试环境中可用为 staging
   * 生产环境中为 https://acme-v01.api.letsencrypt.org/directory
   */
  server: string
  /**
   * 用于接收 let's encrypt 协议的邮箱
   */
  email: string
  /**
   * 是否同意协议
   */
  agreeTos: boolean
  /**
   * 在注册域名获取证书前,会执行这个回调函数
   * string[]: 一组需要注册证书的域名
   * 函数: 第一个参数跟 Options 格式差不多,第二个参数是当前自动获取的域名信息,第三个参数是在处理完之后传递的回调函数
   */
  approveDomains: string[] | (opts, certs: cb) => any
  /**
   * 更新证书最大天数 (以毫秒为单位)
   */
  renewWithin: number
  /**
   * 更新证书的最小天数(以毫秒为单位)
   */
  renewBy: number
}
登入後複製

經過測試,在真實的生產環境中, approveDomains 必須為函數,傳數組的話不會生效。

在生產環境

在生產環境中部署還需要做一些配置變更和引入一些套件。

更新套件:

$ npm i --save greenlock-express@2.x
$ npm i --save le-challenge-fs
$ npm i --save le-store-certbot
$ npm i --save redirect-https
登入後複製

生產代碼:

const greenlock = require('greenlock-express')
const express = require('express')
const app = express()
const lex = greenlock.create({
  // 注意这里要成这个固定地址
  server: 'https://acme-v01.api.letsencrypt.org/directory',
  challenges: { 
    'http-01': require('le-challenge-fs').create({ webrootPath: '~/letsencrypt/var/acme-challenges' }) 
  },
  store: require('le-store-certbot').create({ 
    webrootPath: '~/letsencrypt/srv/www/:hostname/.well-known/acme-challenge' 
  }),
  approveDomains: (opts: any, certs: any, cb: any) => {
    appLog.info('approveDomains', { opts, certs })
    if (certs) {
      /*
       * 注意这里如果是这样写的话,一定要对域名做校验
       * 否则其他人可以通过将域名指向你的服务器地址,导致你注册了其他域名的证书
       * 从而造成安全性问题
       */
      // opts.domains = certs.altnames
      opts.domains = [ 'tasaid.com', 'www.tasaid.com' ]
    } else {
      opts.email = '你的邮箱@live.com'
      opts.agreeTos = true
    }
    cb(null, { options: opts, certs: certs })
  },
})
// 这里的 redirect-https 用于自动将 HTTP 请求跳到 HTTPS 上
require('http').createServer(
  lex.middleware(
    require('redirect-https')()
   )
  ).listen(80, function () {
    console.log('Listening', `for ACME http-01 challenges on: ${JSON.stringify(this.address())}`)
})
// 绑定 HTTPS 端口
require('https').createServer(
    lex.httpsOptions, 
    lex.middleware(app)
  ).listen(443, function () {
    console.log(('App is running at http://localhost:%d in %s mode'), app.get('port'), app.get('env'))
    console.log('Press CTRL-C to stop\n')
})
登入後複製

如果沒有生效,可以檢查下~/letsencrypt 的憑證信息,和443 連接埠是否打開。

部署HTTP/2

HTTP/2 是HTTP/1.1 的升級版,主要來說改進了這些地方:

  1. 二元協定:採用二進位流

  2. 多路復用:一次請求多次重複使用管道

  3. 服务器推送:解决 HTTP/1.x 时代最大的痛点

值的注意的是,HTTP/2 是支持 HTTP 协议的,只不过浏览器厂商都不愿意支持 HTTP,所以基本上可以认为,用上 HTTP/2 的前置条件是必须部署 HTTPS。

SPDY

早在 2009 年,Google 开发了一个实验性协议,叫做 SPDY,目的解决 HTTP/1.x 中的一些设计缺陷。在 SPDY 发布几年后,这个新的实验性协议得到了 Chrome、Firefox 和 Opera 的支持,应用越来越广泛。然后 HTTP 工作组 (HTTP-WG) 在这个 SPDY 的基础上,设计了 HTTP/2,所以可以说 SPDY 是 HTTP/2 的前身。

关于 HTTP/2 的详情可以参考 这篇文章。

部署 HTTP/2

引入 HTTP/2Node.js 中也十分简单,只需要引入 spdy 包即可:

$ npm i --save spdy
登入後複製

然后我们把上一节的代码做一点修改即可支持 HTTP/2:

const greenlock = require('greenlock-express')
const express = require('express')
// HTTP/2
const spdy = require('spdy')
const app = express()
const lex = greenlock.create({
  // 注意这里要成这个固定地址
  server: 'https://acme-v01.api.letsencrypt.org/directory',
  challenges: { 
    'http-01': require('le-challenge-fs').create({ webrootPath: '~/letsencrypt/var/acme-challenges' }) 
  },
  store: require('le-store-certbot').create({ 
    webrootPath: '~/letsencrypt/srv/www/:hostname/.well-known/acme-challenge' 
  }),
  approveDomains: (opts: any, certs: any, cb: any) => {
    appLog.info('approveDomains', { opts, certs })
    if (certs) {
      /*
       * 注意这里如果是这样写的话,一定要对域名做校验
       * 否则其他人可以通过将域名指向你的服务器地址,导致你注册了其他域名的证书
       * 从而造成安全性问题
       */
      // opts.domains = certs.altnames
      opts.domains = [ 'tasaid.com', 'www.tasaid.com' ]
    } else {
      opts.email = '你的邮箱@live.com'
      opts.agreeTos = true
    }
    cb(null, { options: opts, certs: certs })
  },
})
// 这里的 redirect-https 用于自动将 HTTP 请求跳到 HTTPS 上
require('http').createServer(
  lex.middleware(
    require('redirect-https')()
   )
  ).listen(80, function () {
    console.log('Listening', `for ACME http-01 challenges on: ${JSON.stringify(this.address())}`)
})
// HTTP/2
spdy.createServer(lex.httpsOptions, lex.middleware(app)).listen(443, function () {
  console.log('Listening https', `for ACME tls-sni-01 challenges and serve app on: ${JSON.stringify(this.address())}`)
})
登入後複製

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

正则表达式怎么在字符串中提取数字

React中有哪些类定义组件

以上是Node.js怎麼部署HTTPS的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!