关于 javascript:Angular Node(Express) SSL 集成

Angular + Node(Express) + SSL integration

这是我第一次部署 ssl。我在 localhost:4000 上运行了快速节点 js 模块。我已经生成了自签名证书并安装在服务器中并且它正在工作。现在,我的 angularjs 前端在 localhost:3000 上运行(我使用 http-server 来运行 angular 代码)。

为了让我的观点更清楚,这里是服务器端的代码:-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Import node js modules
var https = require('https')
var fs = require('fs')
var express = require('express')

// Load App configuration
var config = require('./config/config')

// Database Integration Here(mongodb)

// Initialize the express app
var app = express()

// App express Configuration

// parse application/json
app.use(bodyParser.json())

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true}))

app.use(cors())

app.set('serverHost', config.server.host)
app.set('serverPort', config.server.port)
app.set('serverUrl', config.server.url)

// Initializing various app modules

// Initialize the components

//Initialize the route(controller)

// Start the app with a given port no and mode
var env = process.env.NODE_ENV || 'development'

var httpsOptions = {
  key: fs.readFileSync(__dirname + '/cert/server.key'),
  cert: fs.readFileSync(__dirname + '/cert/server.crt')
}

https.createServer(httpsOptions, app).listen(app.get('serverPort'), function () {
  // Server and mode info
  console.log('The homerungurus backend running on server: '
              + app.get('serverHost')
              + ' and the port is: '
              + app.get('serverPort'))

  console.log("The mode is:" + env)
})

如您所见,我已在服务器中安装了证书。
我不需要 http 代理,因为我将在标准端口 443 上部署 angular 网络服务器。

我无法理解几件事:-

  • 如何在我的 angular 模块中启用和设置 ssl 证书,以便
    express 和 angular 可以通过 ssl 进行通信。
  • 我将如何向浏览器显示我的后端 Express 节点的证书?
  • 我希望我的观点更清楚了。

    任何帮助表示赞赏?


    好的,我们从哪里开始...

    您有一个在端口 4000 上运行的后端(快速节点 js)和一个在端口 3000 上运行的前端(带有 http-server 的 angularjs),因此您基本上有两个独立的网络服务器在运行。当您说您在服务器上"安装"了 ssl 证书时,我假设您将它放在某个目录中,但实际上并未安装在您的一台服务器上。

    您有多种选择来部署您的代码以及您的 SSL 证书。最好的方法是通过 urls.

    将前端与后端分开

    这意味着您的前端来自:https://frontend.example.com
    并且您的后端从 https://backend.example.com 获得服务(您可以将 url 更改为您想要的任何内容,因此 https://example.com 或 https://www.example.com 之类的内容也很好)

    据我所知,如果您的前端有 https://,那么您的后端也需要 https://,否则浏览器的安全策略会出现问题。您可能还需要寻找同源策略,并在您的服务器上允许 https://frontend.example.com 可以访问 https://backend.example.com,但如果需要,请为此打开一个新票证: D

    用户将看到来自 https://frontend.example.com

    的绿色符号

    我假设您知道如何更改后端 url,以便您的 Angular 代码使用 https://backend.example.com 而不是 http://localhost:4000

    现在要在端口 443 上为您现有的服务器提供服务(这是 https 的默认端口,如果您说 https://...但不指定端口,则始终使用)您需要一个 http 代理。

    作为http代理(你可以谷歌搜索反向代理),你可以使用apache或nginx,两者都很常见。

    那里有几个教程,如何设置特定于操作系统的 nginx/apache,但我相信你会管理。不要忘记为 apache 安装 mod_ssl 和 mod_http_proxy mod(我不记得 nginx 是否也需要特定的东西)

    Apache 反向代理的典型配置如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    <VirtualHost *:80>
        # this part redirects all traffic from normal http to https
        ServerName frontend.example.com
        ServerSignature Off

        RewriteEngine on
        RewriteCond %{HTTPS} !=on
        RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [NE,R,L]
    </VirtualHost>

    <virtualhost *:443>
        # this is the actual part with some security enhancements
        ServerName frontend.example.com
        ServerAdmin webmaster@localhost

        # be carefull with HSTS, it might break your setup if you
        # do not know what you do. If you are not sure, do not
        # comment the next line in
        # Header always add Strict-Transport-Security"max-age=15768000"

        # Enable SSL
        SSLEngine on
        # only strong encryption ciphers
        # for reference https://community.qualys.com/blogs/securitylabs/2013/08/05/configuring-apache-nginx-and-openssl-for-forward-secrecy
        # and no RC4 according to https://community.qualys.com/blogs/securitylabs/2013/03/19/rc4-in-tls-is-broken-now-what
        SSLProtocol all -SSLv2 -SSLv3
        SSLHonorCipherOrder on
        SSLCipherSuite"EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"
        SSLCompression Off
        SSLCertificateFile /path/to/cert.pem
        SSLCertificateKeyFile /path/to/privkey.pem
        # this next line is not needed if you have a self signed cert
        SSLCertificateChainFile /path/to/chain.pem

        ServerSignature Off

        RequestHeader set X-FORWARDED-PROTOCOL https
        RequestHeader set X-Forwarded-Ssl on

        ProxyPreserveHost On

        # Ensure that encoded slashes are not decoded but left in their encoded state.
        # http://doc.gitlab.com/ce/api/projects.html#get-single-project
        AllowEncodedSlashes NoDecode

        <Location />
            # New authorization commands for apache 2.4 and up
            # http://httpd.apache.org/docs/2.4/upgrading.html#access
            Require all granted

            ProxyPassReverse http://127.0.0.1:3000
            ProxyPassReverse http://frontend.example.com/
        </Location>

        #apache equivalent of nginx try files
        # http://serverfault.com/questions/290784/what-is-apaches-equivalent-of-nginxs-try-files
        # http://stackoverflow.com/questions/10954516/apache2-proxypass-for-rails-app-gitlab
        RewriteEngine on
        RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
        RewriteRule .* http://127.0.0.1:3000%{REQUEST_URI} [P,QSA]
        RequestHeader set X_FORWARDED_PROTO 'https'

    您将需要完全相同的两次,对于如上所示的前端和后端,您将端口 3000 替换为 4000,将 frontend.example.com 替换为 backend.example.com.

    我希望这对您有所帮助。它没有尽可能完整,但它应该给你一个提示,如何在 http 代理后面设置你的两个 http 服务器来服务器你的 ssl 证书。


    @chickahoona 的上述评论已经绰绰有余了。我的解决方法如下:-

  • 我删除了 http-server 并在前端使用了 nginx,因为我想要 html5 模式,为此我需要重写 url。
  • 我使用 nginx 作为代理服务器而不是 apache。
  • 就是这样,其他一切都和@chickahoona 指出的一样。