要配置https地址访问,需要向服务器商申请和使用SSL证书。由于是测试阶段,我们自己创建SSL证书,叫作自签名证书。
1.创建自签名证书
- Vue前端生成自签名证书我们用openssl
参考文章一
参考文章二 - SpringBoot后端生成自签名证书用JDK自带的keytool
参考文章一
参考文章二
参考文章三 - 或者直接下载我生成好的自签名证书
由于是自签名证书,所以访问https网址时有不安全提示是正常的,下载链接
2.添加证书
- Vue开发环境下添加证书(vue.config.js文件)
把SSL_test_key放在项目根目录下
js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer:{
//设置https证书
https:{
key: './SSL_test_key/mykey.key',
cert: './SSL_test_key/mycert.crt',
},
port:8080,
//解决报错 chunk-vendors.js:1101 WebSocket connection to 'wss://192.168.0.10:8080/ws' failed:
host: '0.0.0.0',
client: {
webSocketURL: 'ws://0.0.0.0:8080/ws',
},
headers: {
'Access-Control-Allow-Origin': '*',
},
},
})
- SpringBoot添加证书(application.properties文件)
把mykey.p12放到application.properties同级目录下
sh
server.port=8100
server.http.port=80
server.ssl.key-store=classpath:mykey.p12
server.ssl.key-store-password=123456
server.ssl.key-alias=tomcathttps
- 如果是Vue打包,nodejs部署
在dist文件夹同级目录创建server.js脚本
js
// 运行脚本:node server.js
const https = require('https');
const fs = require('fs');
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'dist')));
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
// 设置HTTPS服务器
const options = {
key: fs.readFileSync('./SSL_test_key/mykey.key'), // 替换为你的SSL私钥路径
cert: fs.readFileSync('./SSL_test_key/mycert.crt'), // 替换为你的SSL证书路径
// ca: fs.readFileSync('path/to/your/xxx'), // 可选,替换为你的中间证书路径
};
const port = process.env.PORT || 8080;
// 创建HTTPS服务器
https.createServer(options, app).listen(port); // 监听端口,HTTPS的默认端口是443 这里设置8080
console.log('Server started on port ' + port);
当前文件所在目录运行node server.js
3.设置访问地址
Vue的请求后端的地址需要修改。假设你已经用常量表示了。constants.js
js
export const AIOS_BASE_URL = "https://localhost:8100/api"
export const IMG_BASE_URL = "https://localhost:8100/upload/image/"
把http改成https就可以访问了,浏览器也是输入https前缀。
4、扩展:http请求转发到https
- Vue nodejs http重定向到https
坑1:有文章提到使用express-redirect,但会报不是中间件错误,
坑2:使用路由跳转,会有执行顺序问题,加载静态资源与路由只会执行先出现的,后面的就不执行。
最后用创建服务器时的地址跳转,成功同时加载dist
静态资源,完整server.js
脚本如下:
js
// 运行脚本:node server.js
const https = require('https');
const fs = require('fs');
const express = require('express');
const path = require('path');
const http = require('http');
const url = require('url');
const app = express();
app.use(express.static(path.join(__dirname, 'dist')));
const port = process.env.PORT || 8080;//https端口
//设置HTTP服务器
const httpServer = http.createServer((req, res) => {
// 解析请求,获取路径
const pathname = url.parse(req.url).pathname;
let host = req.headers.host;
host = host.replace(/\:\d+$/, ''); // Remove port number
host += ':'+port;
// console.log(host,pathname);
// 重定向到HTTPS
// res.writeHead(301, { 'Location': `https://${req.headers.host}${pathname}` });//如果http和https都是默认端口 80 443;就不用设置上面的host代码了,直接用这条代码
res.writeHead(301, { 'Location': `https://${host}${pathname}` });
res.end();
});
httpServer.listen(3000,()=>{console.log('HTTP Server started on port 3000');});//设置http端口为3000
// 设置HTTPS服务器
const options = {
key: fs.readFileSync('./SSL_test_key/mykey.key'), // 替换为你的SSL私钥路径
cert: fs.readFileSync('./SSL_test_key/mycert.crt'), // 替换为你的SSL证书路径
// ca: fs.readFileSync('path/to/your/xxx'), // 可选,替换为你的中间证书路径
};
// 创建HTTPS服务器
https.createServer(options, app).listen(port); // 监听端口,HTTPS的默认端口是443 这里设置8080
console.log('HTTPS Server started on port ' + port);
java
package com.zzz.simple_blog_backend.config;
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.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//SpringBoot配置http自动跳转到https
@Configuration
public class Redirect2HttpsConfig {
@Value("${server.http.port}")
private int httpPort;
@Value("${server.port}")
private int httpsPort;
@Bean
TomcatServletWebServerFactory tomcatServletWebServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(){
@Override
protected void postProcessContext(Context context) {
SecurityConstraint constraint = new SecurityConstraint();
constraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
constraint.addCollection(collection);
context.addConstraint(constraint);
}
};
factory.addAdditionalTomcatConnectors(createTomcatConnector());
return factory;
}
private Connector createTomcatConnector() {
Connector connector = new
Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
//监听http端口
connector.setPort(httpPort);
connector.setSecure(false);
//转向https端口
connector.setRedirectPort(httpsPort);
return connector;
}
}