最近项目组完成了个项目,部署到客户那里,客户提供的是Windows服务器并要求部署的站点使用HTTPS安全访问。本来以为是比较简单的事情,给域名申请个证书,然后给站点配置好HTTPS接可以了。结果因为项目是前后端分离的项目,前端域名使用HTTPS访问,导致前端无法通过HTTP请求访问后端的接口,我们必须要为后端的接口也申请证书配置HTTPS。由于后端接口由多个服务提供,那我们需要为不同的后端接口服务申请多个证书并配置HTTPS。客户只给我们申请了前端域名的证书,对于客户来说,他只需要前端访问的域名启用HTTPS,并不关心后端服务是如何访问。所以让客户为所有的后端服务申请证书不现实,那么我们要如何解决这个问题呢。
前后端分离的项目中,只有一个带证书的域名的情况下,需要让项目启用HTTPS并正确的跑起来。
通过调研和对比,最终采用Nginx反向代理服务来处理。Nginx监听带证书的HTTPS的域名,将根路径指向前端Vue项目的物理路径,后端的服务通过二级目录来转发。这样项目所有的后端接口服务都使用HTTPS的二级路径来转发,HTTPS的前端网站请求HTTPS的二级路劲访问后端接口。使用Nginx反向代理解决了前后端项目只有一个带证书的HTTPS域名无法让网站跑起来的问题。
由于客户提供的是Windows服务器,所以我们需要在Windows服务器上安装Nginx。Nginx官方下载地址:http://nginx.org/en/download.html,这里我们下载最新的Windows版本(当前版本为1.19.5)的Nginx即可:
下载之后解压文件,Nginx的目录结构如下:
打开conf目录编辑nginx.conf配置文件,nginx.conf配置文件中包含一些示例配置,我们只需要参考给的示例配置以及官方的配置文档即可满足绝大部分的需求。官方配置文档:http://nginx.org/en/docs/beginners_guide.html。默认的nginx.conf文件内容:
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
打开cmd命令行工具 ,切换到nginx-1.19.5目录,直接start nginx命令启动nginx。如果默认的80端口未被占用,浏览器中访问localhost则可以看到nginx中的默认index.html页面内容。Windows中nginx相关命令:
start nginx run nginx 启动nginx nginx -s stop fast shutdown 快速停止 nginx -s quit graceful shutdown 正常停止 nginx -s reload changing configuration, starting new worker processes with a new configuration, graceful shutdown of old worker processes 修改配置后,正常关闭之前的进程,并使用新的配置启动新的进程 nginx -s reopen re-opening log files 重新打开日志文件 nginx -t test the configuration file: nginx checks the configuration for correct syntax, and then tries to open files referred in the configuration. 测试配置文件:nginx检查配置的语法是否正确,然后尝试打开配置中引用的文件。 tasklist /fi "imagename eq nginx.exe" Run the tasklist command-line utility to see nginx processes 使用tasklist命令行查看运行的nginx进程
参考nginx提供的默认配置,根据我们的需求修改nginx.conf配置,首先配置HTTPS,HTTPS根目录配置给vue前端站点,二级目录配置给后端接口服务。然后配置HTTP,让HTTP的请求转发到HTTPS上,配置示例如下:
# 配置片段
# HTTPS server 配置HTTPS监听
#
server {
listen 443 ssl;
server_name localhost; # 修改为自己的域名
ssl_certificate cert.pem; # 证书pem文件地址,可以是相对路径或绝对路径
ssl_certificate_key cert.key; # 证书key文件地址,可以是相对路径或绝对路径
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# 域名的根路径配置为vue前端站点
location / {
root vue; # 前端vue根目录,可以是相对路径或者绝对路径
index index.html; # 前端vue页面html文件
}
# 给后端服务接口配置二级目录
location /user-api/ {
proxy_pass http://127.0.0.1:8081/; # 转发给用户接口服务
}
# 给后端服务接口配置二级目录
location /product-api/ {
proxy_pass http://127.0.0.1:8082/; # 转发给产品接口服务
}
}
# HTTP server 配置HTTP监听
#
server {
listen 80;
server_name localhost; # 修改为自己的域名
rewrite ^(.*) https://$server_name$1 permanent; # 访问http请求,跳转到https地址上
}
至此Nginx的配置已经完成,然后我们需要将vue前端访问后端接口地址修改为nginx中配置的HTTPS域名的二级目录,重新打包发布vue前端项目。最后运行nginx,一个前后端分离的项目配置HTTPS就完全解决了。
Windows服务器上如何将nginx注册为服务,这样服务器重启的时候可以自动启动nginx,保证nginx高可用?
使用NSSM将nginx注册为服务,在命令行中运行 nssm install N1 "nginx.exe" 将nginx注册为服务。该方案来自网络,博主没有测试,不过应该可行,参考SpringBoot项目注册为windows服务。
如果nginx配置监听的端口被占用如何处理?
如果nginx监听的端口被占用了,nginx是无法监听占用了的端口的,所以首先我们需要查询是什么程序或者服务占用了端口,然后将占用端口的程序停掉或者修改为使用其他端口,之后再启动nginx。由于Windows服务器上已经安装了IIS并且部署了多个IIS站点,这种情况很可能80端口已经被占用,占用80端口的情况有很多种我们需要根据具体的情况做处理。一般有这几个步骤:
1.首先cmd命令行中,通过 netstat -aon | findstr :80 查询占用端口的任务以及对应的PID。
2. 打开任务管理器,通过PID查找占用端口的任务,如果暂用的任务不是系统必须的也不是我们需要的,可以直接结束掉,可能就释放80端口了。如果是System的任务,那么需要再继续分析。
3.命令行中输入 netsh http show servicestate指令继续查看http的服务状态,看有哪些服务占用80端口。
4.切换到任务管理器,通过PID查找占用端口的服务,如果服务不是我们需要的,我们可以在系统服务中直接停用,可能80端口就释放了。
5. 如果80端口被http.sys占用,而我们又需要依赖http.sys的应用或者服务的时候,那么可以通过 netsh http add iplisten ipaddress=:: 命令修改http.sys监听的地址或端口,让http.sys只监听指定地址或者端口,从而让域名对应的80端口释放出来。该方案博主未亲自测试,应该使可行的,参考文末参考地址的几篇博客。
前后端分离的项目中,如果前端启用HTTPS,那么前端请求的后端接口也需要是HTTPS的。本文将项目中真实的场景做一个介绍,并在windows服务器上通过nginx反向代理,解决了只有一个带证书的域名情况下,如果让前后端分离的项目启用HTTPS。虽然以前没使用过nginx,但是网络上相关资料丰富,本以为是一个比较容易的配置,可最终还是花了一些时间在这件事上面。nginx的配置还是比较简单,主要的时间花在分析80端口被占用上。这里以博客的形式做一个记录和分享,同时希望可以给其他网友一些参考。如果有描述不正确的地方,希望各位网友反馈指正。
用 nssm 把 Nginx 安装成 Windows 服务方法
Windows Sever关于80端口之争
Windows下80端口被进程System占用的解决方法
遇到了“80端口被占用”的问题,该如何解决?
Netsh http 命令