基于Nginx解决前端访问服务器跨域问题(Session和cookie无效)

简介:

问题背景

这两天遇到一个这样的需求:

有两个项目a和b,在a项目中有页面需要调用b中的接口,两项目的域名不同,分别为a.com, b.com。这时候如果直接调用,显然跨域了。一番折腾之后,问题解决了,这里记录一下解决方法。

解决方法

第一步,解决跨域

这个使用Nginx的代理功能即可,在a服务器的Nginx添加如下示例配置:

location ~ /xxx/ {
proxy_pass http://b.com;
}

这样就把路径中带有/xxx/的请求都转到了b.com。如果不需要保存cookie,保持session这样的功能,这样就可以了。

然而,本项目就是要用到cookie,所以就有了下边的内容。

第二步,设置domain

因为cookie当中是有domain的,两个服务器的一般不同,比如a服务器返回的Response Headers中是

Set-Cookie:JSESSIONID=_3y4u02v4cbpBw10DoCrMSnjg7m34xuum1XRWBF1Uno; path=/; domain=a.com

而b服务器返回的是

Set-Cookie:JSESSIONID=_3y4u02v4cbpBw10DoCrMSnjg7m34xuum1XRWBF1Uno; path=/; domain=b.com

这时候如果a项目的页面调用了b的接口,浏览器发现接口返回的domain不是a.com,就不会把cookie保存起来,session也就失效了。Nginx 引入了proxy_cookie_domain来解决这个问题。示例:

location ~ /xxx/ {
proxy_cookie_domain b.com a.com;
proxy_pass http://b.com;
}

这样就可以在Nginx转接请求的时候自动把domain中的b.com 转换成 a.com,这样cookie就可以设置成功了。

但是,对于有些情况这样转换不灵光。比如,b项目的domain是.b.com,前边多了一个小点,那对应的改为 proxy_cookie_domain .b.com a.com; 可以不?通过实践,不行!!!

通过查看Nginx文档,找到了解决办法。其实,除了上边那种配置方式外,Nginx还支持正则配置:

location ~ /xxx/ {
proxy_cookie_domain ~\.?b.com a.com;
proxy_pass http://b.com;
}

这样就可以把domain中的.b.com 转换成 a.com啦。

第三步,设置path

正常情况下完成以上两步就可以了,因为cookie中的path一般默认的是path=/,也就是所有请求都可以访问本cookie。但有些服务器会指定,只允许某个层级下的请求可以访问cookie,比如:

Set-Cookie:JSESSIONID=_3y4u02v4cbpBw10DoCrMSnjg7m34xuum1XRWBF1Uno; path=/sub/; domain=b.com

这样就只允许相对根路径,以/sub/开头的请求路径才能访问cookie。这时候就又可能出现cookie无效的问题了,为了解决这个问题,可以使用proxy_cookie_path。示例:

location ~ /xxx/ {
proxy_cookie_domain ~\.?b.com a.com;
proxy_cookie_path /sub/ /;
proxy_pass http://b.com;
}

这样就把只允许/sub/层级下的请求访问cookie,改为允许所有请求访问cookie了。

总结

折腾了几个小时,还是在Nginx官方文档找到了解决方案。说了这么多,其实只要这样简单的几行配置就可以搞定跨域cookie了。希望本文能够对你有所帮助。

备注

Nginx文档节选内容:

Syntax: proxy_cookie_domain off;
proxy_cookie_domain domain replacement;
Default:
proxy_cookie_domain off;
Context: http, server, location

This directive appeared in version 1.1.15.

Sets a text that should be changed in the domain attribute of the “Set-Cookie” header fields of a proxied server response. Suppose a proxied server returned the “Set-Cookie” header field with the attribute “domain=localhost”. The directive

proxy_cookie_domain localhost example.org;

will rewrite this attribute to domain=example.org.

A dot at the beginning of the domain and replacement strings and the domain attribute is ignored. Matching is case-insensitive.

The domain and replacement strings can contain variables:

proxy_cookie_domain www.$host $host;

The directive can also be specified using regular expressions. In this case, domain should start from the “~” symbol. A regular expression can contain named and positional captures, and replacement can reference them:

proxy_cookie_domain ~.(?P-0-9a-z+.a-z+)$ $sl_domain;

There could be several proxy_cookie_domain directives:

proxy_cookie_domain localhost example.org;
proxy_cookie_domain ~.(a-z+.a-z+)$ $1;

The off parameter cancels the effect of all proxy_cookie_domain directives on the current level:

proxy_cookie_domain off;
proxy_cookie_domain localhost example.org;
proxy_cookie_domain www.example.org example.org;
proxy_cookie_path off;
proxy_cookie_path path replacement;

Default:

proxy_cookie_path off;
Context: http, server, location

This directive appeared in version 1.1.15.

Sets a text that should be changed in the path attribute of the “Set-Cookie” header fields of a proxied server response. Suppose a proxied server returned the “Set-Cookie” header field with the attribute “path=/two/some/uri/”. The directive

proxy_cookie_path /two/ /;

will rewrite this attribute to “path=/some/uri/”.

The path and replacement strings can contain variables:

proxy_cookie_path $uri /some$uri;

The directive can also be specified using regular expressions. In this case, path should either start from the “~” symbol for a case-sensitive matching, or from the “~*” symbols for case-insensitive matching. The regular expression can contain named and positional captures, and replacement can reference them:

proxy_cookie_path ~*^/user/(^/+) /u/$1;

There could be several proxy_cookie_path directives:

proxy_cookie_path /one/ /;
proxy_cookie_path / /two/;

The off parameter cancels the effect of all proxy_cookie_path directives on the current level:

proxy_cookie_path off;
proxy_cookie_path /two/ /;
proxy_cookie_path ~*^/user/(^/+) /u/$1;

参考文档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain

1,Nginx英文帮助文档

2,Nginx中文帮助文档

往期文章

Nginx系列教程(1)nginx基本介绍和安装入门

Nginx系列教程(2)nginx搭建静态资源web服务器

Nginx系列教程(3)nginx缓存服务器上的静态文件

Nginx系列教程(4)nginx处理web应用负载均衡问题以保证高并发

Nginx系列教程(5)如何保障nginx的高可用性(keepalived)

Nginx系列教程(6)nginx location 匹配规则详细解说

Nginx系列教程(7)nginx rewrite配置规则详细说明

Nginx系列教程(8)nginx配置安全证书SSL

Nginx系列教程(9)nginx 解决session一致性

相关文章
|
2月前
|
前端开发 JavaScript API
前端如何访问文件夹
前端如何访问文件夹
前端如何访问文件夹
|
19天前
|
前端开发 JavaScript Java
前端解决axios请求的跨域问题【2步完成】
本文介绍如何通过前端配置解决跨域问题,主要针对Vue项目中的`vite.config.js`文件进行修改。作者在联调过程中遇到跨域报错
31 1
|
2月前
|
存储 前端开发 Java
【SpringMVC】——Cookie和Session机制
获取URL中参数@PathVarible,上传文件@RequestPart,HttpServerlet(getCookies()方法,getAttribute方法,setAttribute方法,)HttpSession(getAttribute方法),@SessionAttribute
|
3月前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
3月前
|
存储 安全 搜索推荐
理解Session和Cookie:Java Web开发中的用户状态管理
理解Session和Cookie:Java Web开发中的用户状态管理
107 4
|
3月前
|
前端开发 JavaScript 安全
揭秘!前端大牛们如何高效解决跨域问题,提升开发效率!
【10月更文挑战第30天】在Web开发中,跨域问题是一大挑战。本文介绍前端大牛们常用的跨域解决方案,包括JSONP、CORS、postMessage和Nginx/Node.js代理,对比它们的优缺点,帮助初学者提升开发效率。
123 4
|
3月前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
4月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
267 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
4月前
|
存储 安全 数据安全/隐私保护
Cookie 和 Session 的区别及使用 Session 进行身份验证的方法
【10月更文挑战第12天】总之,Cookie 和 Session 各有特点,在不同的场景中发挥着不同的作用。使用 Session 进行身份验证是常见的做法,通过合理的设计和管理,可以确保用户身份的安全和可靠验证。
71 1
|
4月前
axios允许跨域cookie
axios允许跨域cookie
42 3

热门文章

最新文章

  • 1
    DeepSeek Artifacts:在线实时预览的前端 AI 编程工具,基于DeepSeek V3快速生成React App
  • 2
    【Java若依框架】RuoYi-Vue的前端和后端配置步骤和启动步骤
  • 3
    2025年前端局势分析,我该不该转行?
  • 4
    【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 5
    前端 CSS 优化:提升页面美学与性能
  • 6
    《前端技术基础》第01章 HTML基础【合集】
  • 7
    【01】vs-code如何配置flutter环境-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈-供大大的学习提升
  • 8
    【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
  • 9
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 10
    【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈