部署单页应用 SPA 时,我们通常使用 Nginx 做中间层进行转发代理。为了保护 Web 安全,要求我们使用 HTTPS(HTTP + SSL) 以及 WSS(Websocket + SSL) 进行通信。HTTPS 及 WSS 协议旨在保护用户数据在网络上不被窃听(机密性) 和不被篡改(完整性)。
进入腾讯云服务器 - 搜索SSL证书 - 证书管理- 申请免费的SSL证书
审核通过将证书下载到本地解压,解压结果获得5个文件,如下图:
通过Nginx配置证书,我们只需Nginx文件下的证书文件和私钥文件传到服务器, 并放到Nginx的配置文件路径
1_www.sitven.cn_bundle.crt
证书文件2_www.sitven.cn.key
私钥文件(注意:如果在申请或者购买ssl证书设置了秘钥,则该文件不存在,配置使用之前设置的密码即可)配置文件路径:/usr/local/nginx/conf (此处为默认安装目录,请根据实际情况操作)
编辑 Nginx 根目录下的配置文件nginx.conf
文件。修改内容如下:
注:此操作可通过执行 vim /usr/local/nginx/conf/nginx.conf
命令行编辑该文件。由于版本问题,配置文件可能存在不同的写法
例如:Nginx 版本为 nginx/1.15.0
以上请使用 listen 443 s
sl
代替 listen 443
和 ssl on
server {
#SSL 访问端口号为 443
listen 443 ssl;
#填写绑定证书的域名
server_name www.sitven.cn;
#证书文件名称
ssl_certificate 1_www.sitven.cn_bundle.crt;
#私钥文件名称
ssl_certificate_key 2_www.sitven.cn.key;
ssl_session_timeout 5m;
#请按照以下协议配置
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
# 网站主页路径, 此为我博客项目。此路径仅供参考,具体按照实际需求操作
uwsgi_pass 127.0.0.1:8001;
include /etc/nginx/uwsgi_params;
}
}
配置完成,可通过执行以下命令验证配置文件问题
sudo nginx -t
若存在问题,请您重新配置或者根据提示修改存在问题
比如证书和私钥文件没放到正确的路径, Nginx
就会提示没有这样的文件,如下图:
我们根据错误提示将证书与私钥放到正确的路径后重新进行验证
若配置不存在问题,如下图:
我们重启 Nginx,即可使用 李文君的个人博客
进行访问
http
协议通过80
端口通讯的而https
协议通过443
端口通讯, 所以我们需要做一个重定向, 把80端口的请求重定向到443端口,我们在Nginx配置文件的上一个代码块基础上增加一个server节点提供重定向服务
1. server {
2. listen 80;
3. server_name www.你的域名.cn;
4. rewrite ^(.*)$ https://${server_name}$1 permanent;
5. }
如此,我们通过http协议访问网站时会自动重定向到https
第一次接触wss本以为只要在nginx里面做配置即可,但是我们想想nginx只帮我们做一个代理转发的功能,实际上要想websocket支持wss协议,我们就必须让我们的web服务支持https协议,所以继续在我们的后端服务器做配置
接下来就要使用tomcat文件下的jks文件了
将证书复制到项目中并进行配置
打开我们的项目目录,在src->main->resources中,把我们刚刚的证书文件放进去
打开application配置文件,添加如下代码
其中key-store: 填写你的pfx证书文件,比如key-store: classpath:1234567_baidu.cn.pfx
key-store-password: 填写pfx-password.txt文件中的密码
(注意!!!每个属性的分号后面必须加个空格,比如port: 443,而不是port:443)
server:
port: 443
ssl:
key-store: classpath:15XXXXXXXXXX.cn.pfx
key-store-type: PKCS12
key-store-password: 这里填pfx-password.txt的文件内容(如果没有则填证书申请时的秘钥)
或者使用application.properties添加的内容如下(与上二选一即可):
我们启动试试:发现启动协议为https即配置成功
到这里我们就可以测试一波了,当然我相信你启动的时候会有各种环境依赖问题 哈哈哈哈哈~~~~
websocket在线测试工具: Websocket在线测试-Websocket接口测试-Websocket模拟请求工具
成功截图:
当然有朋友就会问了,这样我们该模块下的其它接口就只能通过https来访问了,其实我们还可通过后端配置让其也支持http请求,当然可根据业务需求还确认。
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* http重定向到https
* @return
*/
@Configuration
public class SecurityConfig
{
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(httpConnector());
return tomcat;
}
@Bean
public Connector httpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
//Connector监听的http的端口号
connector.setPort(8080);
connector.setSecure(false);
//监听到http的端口号后转向到的https的端口号
connector.setRedirectPort(443);
return connector;
}
}
附上我遇到的一个依赖问题,无法加载jks文件,修改pom文件新增插件配置
org.springblade
blade-service
2.8.0.RELEASE
true
4.0.0
blade-websocket
${project.artifactId}
${bladex.project.version}
jar
org.springblade
blade-core-boot
org.springblade
blade-starter-swagger
cn.hutool
hutool-all
5.5.4
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.5
junit
junit
4.12
org.springframework
spring-websocket
5.0.8.RELEASE
compile
javax.websocket
javax.websocket-api
1.1
provided
chat
src/main/resources
true
*.keystore
*.jks
*.*.jks
*.p12
src/main/resources
false
*.keystore
*.*.jks
*.jks
*.p12
org.apache.maven.plugins
maven-resources-plugin
3.1.0
org.apache.maven.plugins
maven-dependency-plugin
copy-dependencies
package
copy-dependencies
${project.build.directory}/lib
false
false
false
true
runtime
其实你会发现配置不难,是各种环境报错而走的很多弯路,本文分享希望可以帮助到您,点赞哦!
完整配置参考:
server {
listen 1888;
server_name pingan.net www.pingan.net; # 填写自己的域名
rewrite ^(.*) https://www.$server_name$1:1888 permanent; # 地址重写http----https
}
server {
listen 443 ssl; #https监听端口
server_name www.pingan.net;
charset utf-8;
# ssl on;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate /etc/nginx/1_pingan.net_bundle.crt;
ssl_certificate_key /etc/nginx/2_pingan.net.key;
location / {
root /data/app/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location /api/ {
proxy_pass http://localhost/;
}
# 本地服务websokcet通讯接口
location /websocket/ {
proxy_pass http://www.pingan.net:9001; # 填写自己的域名 代理到http
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
# 默认60s断开连接
proxy_read_timeout 60s;
}
}