X-Accel-Redirect
这篇博客来源于团队最近的项目方案。团队最近接了一些合作项目,合作项目免不了要加密/解密、加签/解签来保证基本的信息安全。以前,业务团队是有一套标准的算法供合作方接入,不过难免有些合作项目要按对方的标准来接入。
- 方案一:业务团队都是针对合作方开发,定制接口;
- 方案二:架一个适配层系统,将业务解放出来。
方案一对业务系统侵入大,而且开发、维护成本高,方案二比较好。但是适配层系统如何将请求转发到业务系统?nginx提供的内部重定向(X-Accel-Redirect)机制是一个比较好的方式。适配层系统在处理完特殊的解签后,在response里加一个header(X-Accel-Redirect)指定请求转发的路径(业务标准实现的路径),nginx收到响应报文不会返回给客户端,而是从指定的业务路径中请求内容返回客户端。
用了X-Accel-Redirect机制以后,对外合作项目的请求到达业务系统已经是标准的结构了。请求路径如下:
为什么用内部重定向而不直接用重定向,内部重定向有以下几点优势:
- 用户感觉不到跳转;
- 业务标准的路径不用暴露;
- 少一次网络请求。
举例
写两个接口(/focuse/hello、/focuse/hello2),其中/focuse/hello返回时设置"Accel-Redirect=/focuse/hello2"。我们请求/focuse/hello期望输出"redirect to hello2!",而不是"hello world!"
/**
* @author :
* @date :Created in 2020/5/15 下午11:56
* @description:
* @modified By:
*/
@RestController
@RequestMapping("/focuse")
public class WebSiteController {
@RequestMapping("hello")
public String hello(HttpServletResponse response) throws Exception{
response.setHeader("X-Accel-Redirect", "/focuse/hello2?custom=" + URLEncoder.encode("redirect to hello2!", "UTF-8"));
return "hello world!";
}
@RequestMapping(value = "hello2")
public String hello2(@RequestParam("custom") String custom) {
return custom;
}
}
启动应用,端口是8080
配置nginx并启动,nginx监听的端口是80,nginx配置80请求代理到8080端口
server {
listen 80;
location / {
proxy_pass http://$host:8080;
}
}
请求:http://127.0.0.1/focuse/hello 输出redirect to hello2,并且浏览器地址栏还是focuse/hello(用户无感知)
使用nginx配置案例:
X-Accel-Redirect 是一种由 Nginx 提供的内部重定向机制,它可以将客户端请求重定向到 Nginx 服务器本地的一个文件路径上。这个特性通常用于加速 Web 应用程序处理静态文件。
以下是一个 Nginx 配置示例,演示如何使用 X-Accel-Redirect 实现内部重定向:
server {
listen 80;
server_name example.com;
# Location block to handle the incoming request
location / {
# Call Java API for authentication
proxy_pass http://localhost:8080/auth;
# If authenticated, perform internal redirect using X-Accel-Redirect header
if ($http_x_auth_ok = "true") {
add_header X-Accel-Redirect /internal;
}
}
# Location block for internal redirect
location /internal {
internal;
proxy_pass http://localhost:8080/app;
}
}
以上是一个简单的nginx.conf配置,实现了在请求进入nginx后,调用后端Java接口进行鉴权,如果鉴权成功,则使用X-Accel-Redirect进行内部重定向:
以下是一个简单的测试案例,包括响应结果的输出和展示浏览器上的请求地址变化情况。测试案例要求浏览器的请求地址不变。
- 启动nginx服务器和后端Java接口服务器。
- 打开浏览器,输入URL:http://example.com/test。
- 检查后端Java接口服务器是否接收到了鉴权请求,并返回了相应的响应结果。
- 如果鉴权成功,则浏览器上显示的请求地址不变,并且页面内容为经过重定向后的页面内容。
- 如果鉴权失败,则显示相应的错误信息。