jfinal redirect 到https没有效果

我已经升级到jfinal3.4了,重定向到https依然无法使用。

redirect("view?orderId=" + order.getId());

This request has been blocked; the content must be served over HTTPS.

评论区

2020-06-15 17:16

@jfinal爱好者22 你这个redirect 没有到https吧,默认是到http的

jfinal爱好者22

2020-06-15 17:21

@谢 之前是http的,然后网站换成https的了,然后redirect重定向就跳转不了了,这个改怎么解决啊

2020-06-15 17:23

@jfinal爱好者22 你要是用代理的话,就得做处理了。要不是代理的话,应该是没问题的。用代理的话,获取到的头部都是http的。

2020-06-15 17:24

@jfinal爱好者22 https://jfinal.com/feedback/1925

jfinal爱好者22

2020-06-15 17:37

@谢 好的,谢谢了

jfinal爱好者22

2020-06-15 18:42

@谢 我按照你的文档,做了。还是不行啊 nginx修改:
location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
}

Java 后台:因为我的是3.4版本,继承RedirectRender之后,这三个参数url,withQueryString,contextPath我有定义了一下,private String url;
private boolean withQueryString;

private static final String contextPath = getContxtPath();
package com.jfinalshop.render;

import com.jfinal.core.JFinal;
import com.jfinal.kit.StrKit;
import com.jfinal.render.RedirectRender;

/**
* RedirectRender with status: 302 Found.
*
*
* 注意:使用 nginx 代理实现 https 的场景,解决 https 被重定向到了 http 的问题,需要在 nginx 中添加如下配置:
* proxy_set_header X-Forwarded-Proto $scheme;
* proxy_set_header X-Forwarded-Port $server_port;
*
*
* PS:nginx 将 http 重定向到 https 的配置为:
* proxy_redirect http:// https://;
* 注意: 需要同时支持 http 与 https 的场景不能使用该配置
*
*/
public class MyRedirectRender extends RedirectRender {

private String url;
private boolean withQueryString;

private static final String contextPath = getContxtPath();

static String getContxtPath() {
String cp = JFinal.me().getContextPath();
return !"".equals(cp) && !"/".equals(cp) ? cp : null;
}

public MyRedirectRender(String url) {
super(url);
}

public MyRedirectRender(String url, boolean withQueryString) {
super(url, withQueryString);
}

@Override
public String buildFinalUrl() {
String ret;
// 如果一个url为/login/connect?goto=http://www.jfinal.com,则有错误
// ^((https|http|ftp|rtsp|mms)?://)$ ==> indexOf 取值为 (3, 5)
if (contextPath != null && (url.indexOf("://") == -1 || url.indexOf("://") > 5)) {
ret = contextPath + url;
} else {
ret = url;
}

if (withQueryString) {
String queryString = request.getQueryString();
if (queryString != null) {
if (ret.indexOf('?') == -1) {
ret = ret + "?" + queryString;
} else {
ret = ret + "&" + queryString;
}
}
}

// 跳过 http/https 已指定过协议类型的 url,用于支持跨域名重定向
if (ret.toLowerCase().startsWith("http")) {
return ret;
}

/**
* 注意:nginx 代理 https 的场景,需要使用如下配置:
* proxy_set_header X-Forwarded-Proto $scheme;
* proxy_set_header X-Forwarded-Port $server_port;
*/
if ("https".equalsIgnoreCase(request.getHeader("X-Forwarded-Proto"))) {
String serverName = request.getServerName();

/**
* 获取 nginx 端通过配置 proxy_set_header X-Forwarded-Port $server_port;
* 传递过来的端口号,保障重定向时端口号是正确的
*/
String port = request.getHeader("X-Forwarded-Port");
if (StrKit.notBlank(port)) {
serverName = serverName + ":" + port;
}

if (ret.charAt(0) != '/') {
return "https://" + serverName + "/" + ret;
} else {
return "https://" + serverName + ret;
}

} else {
return ret;
}
}
}

jfinal爱好者22

2020-06-15 18:50

@谢 需要在JFinalConfig里面添加什么吗?

杜福忠

2020-06-15 19:54

proxy_set_header Host $host:443;写死

JFinal

2020-06-15 20:47

@jfinal爱好者22 当使用 nginx 做代理时,nginx 与用户客户端/浏览器之间使用的是 https 以及端口号 443。 而 nginx 与你的项目之间使用的是 http 与类似 8080 这样的端口

从而,在 jfinal 的 RedirectRender 中所能看到的仍然只可能是 http 与 8080, 而看不到 https 与 443

所以,解决的思路必定是将 nginx 所知晓的 https 与 443 传递到 RedirectRender 中

有了上述的铺垫,解决起来就容易了,首先在 nginx 中添加如下两行配置,将 https、443 这两个值传递给你的项目:
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;


然后将线上的 jfinal 最新 RedidrectRender.java 源码复制出来:
https://gitee.com/jfinal/jfinal/blob/master/src/main/java/com/jfinal/render/RedirectRender.java

将复制出来的源码做成一个自己的 MyRedirectRender extends Render{
复制出来的源码放这里
}

使用的时候这样:
render(new MyRedirectRender(...));


当然,你也可以继承 RenderFactory,将你自己的 MyRedirectRender 替换掉 jfinal 自带的 RedirectRender

maven 中心库的 jfinal 4.9 并未完全解决这个问题,线上提交的这个才完美解决。

JFinal

2020-06-15 20:53

@jfinal爱好者22 忘了上次详细回复过这个问题,况且解决方案也有下载:
https://jfinal.com/feedback/1925

下载地址:
http://free-download.jfinal.com/download/MyRenderFactory.zip

jfinal爱好者22

2020-06-15 21:22

@JFinal 好的,谢谢了。我试试。还有我项目里面很多地方用到redirect(),这个方法,都要把redirect()改成render(new MyRedirectRender(...))吗,

JFinal

2020-06-15 22:27

@jfinal爱好者22 下载我上一条回复中链接的文件,可配置扩展来解决

配置以后,保持你以前的用法 redirect(...) 即可

JFinal

2020-07-25 17:08

后续补充, 新版本 jfinal 4.9.01 已经将上述方案添加进来,可以升级到该版本解决问题,注意仍然需要在 nignx 中添加配置才能支持,配置方法如下:
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;

具体原因见本贴前面详细的回复

jfinal爱好者22

2020-07-29 16:06

@JFinal 好的,谢谢