nginx通过域名访问项目(不接项目名称),cookie丢失问题详解

nginx通过域名访问项目(不接项目名称),cookie丢失问题详解
最近搞了个域名,想用它直接去访问Tomcat上部署的项目,开始一直必须加上项目名称,经过短暂配置,成功了。

访问一次,到达登陆页面,结果死活登录不进去,一直在登陆界面,原来是由于cookie丢失,现配置如下,完美解决问题:

server {
        listen       80;
        #listen       somename:8080;
        server_name www.XXX.cn;

        location / {
            proxy_pass http://IP:8080/projectName/;
            proxy_cookie_path /projectName/ /;
           proxy_set_header   Host    $host;
           proxy_set_header   X-Real-IP   $remote_addr;
           proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            #root   html;
            #index  index.html index.htm;
        }
        location /projectName/ {
           proxy_pass http://IP:8080/projectName/;
           proxy_cookie_path /projectName/ /;
           proxy_set_header   Host    $host;
           proxy_set_header   X-Real-IP   $remote_addr;
           proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
       }
    }

proxy_cookie_path /projectName/ /; 用于改变cookie路径,解决cookie丢失问题的

在配置域名访问应用时,常出现cookie丢失问题,原因是普通的配置cookie的路径为(没有经过代理的地址): http://IP:8080/projectName cookie_path:/project

但是为了不添加项目名就能访问应用,我们把location的代理地址设置为/ ,所以要改变cookie的路径,语法: proxy_cookie_path path replacement;

path就是你需要替换的路径,replacement就是你需要替换的值

proxy_set_header Host $host;

host变量的值按照如下优先级获得:

  1. 请求行中的host.
  2. 请求头中的Host头部.
  3. 与一条请求匹配的server name.

很清楚,有三点,取优先级最高的那个。仅从字面意思上来理解,这个选择的过程为:如果请求行中有host信息,则以请求行中的host作为host变量的

值(host与host变量不是一个东西,很拗口);如果请求行中没有host信息,则以请求头中的Host头的值作为host变量的值;如果前面两者都没有,那

么host变量就是与该请求匹配所匹配的serve名。

proxy_set_header X-Real-IP $remote_addr; 用于获取用户真实IP的

详解如下:

经过反向代理后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$remote_addr变量拿到的将是Nginx的ip地址,

但是Nginx是可以获取用户的真实IP的,也就是说Nginx通过$remote_addr变量时获取的就是用户真实IP,那么想在web服务器获取用户真实IP,那咱们就需要赋

值一下,如上面的配置,Nginx将用户的真实IP赋值给X-Real-IP,然后在web端request.getAttribute(“X-real-ip”)获取IP

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 用于获取用户真实IP的

另附上获取IP的工具

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

/**
 * 常用获取客户端信息的工具
 * 
 */
public final class NetworkUtil {

    /**
     * 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址;
     * 
     * @param request
     * @return
     * @throws IOException
     */
    public final static String getIpAddress(HttpServletRequest request) throws IOException {
        // 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址

        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");

            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");

            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();

            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_40814247/article/details/88052777