Nginx 反向代理及 Cookie 相关问题
最近一個項目,遇到了Nginx反向代理和Cookie的問題,遇到的問題很雜,經(jīng)過一周多逐步摸索,總算有個解決方案了,做個記號,主要是記錄下遇到問題的過程,以便出現(xiàn)問題時備查。
【背景】
【問題及解決辦法】
問題1:手機端需要從外網(wǎng)訪問,沒有域名,沒有越獄或root的手機是不能修改hosts的,且Domino服務(wù)器必須通過域名訪問。
解決方案:
問題2:Domino中,鏈接中/符號引發(fā)的問題
由于Domino的技術(shù)特點,很多鏈接都是需要寫上/的,如:src="/names.nsf?xxx",有的是頁面中這樣寫的,也有的是通過302跳轉(zhuǎn)時自動跳到這個位置,這一點與Java應(yīng)用不同,Java應(yīng)用中更多的是相對位置,不用寫這個/。這個符號導(dǎo)致的問題如下:本來希望通過http://nginx_server/myapp/的方式來訪問,將請求轉(zhuǎn)發(fā)至http://domino_server/,這個需求可以通過在nginx.conf中這樣設(shè)置解決:
?
location /myapp {proxy_pass http://domino_server/; }但是由于/的作用,導(dǎo)致直接訪問到了http://nginx_server/,而不再通過/myapp,導(dǎo)致報頁面內(nèi)容找不到。
解決方案:
所以還需要在Nginx中,增加對/的反向代理:
?
location / {proxy_pass http://domino_server/; }問題3:認證問題
Domino服務(wù)器中,通過寫了一些接口代碼,提供RESTful的服務(wù),來對手機端進行提供服務(wù)。但是由于原來的環(huán)境,沒有SSO,而且不通過認證,沒法訪問到Domino里面的接口代碼。
解決方案:
手機端通過HTTP,模擬登錄過程
問題4:“問題3”的解決方案,由于經(jīng)過了反向代理,導(dǎo)致Domino的Response中Cookie的Domain屬性,與反向代理的域名不一致,Cookie的Domain屬性,仍然是Domino服務(wù)器的域名。手機端拿到Cookie之后,再次進行請求的話,請求是發(fā)往反向代理的,瀏覽器認為之前拿到的Cookie不屬于反向代理,所以Request的時候,不會把Cookie帶上,導(dǎo)致認證不能通過。
解決方案:
?
location / {proxy_cookie_domain domino_server nginx_server; }在Nginx上這樣設(shè)置后,可以讓反向代理修改Cookie的Domain屬性。
問題5:“問題4”的解決方案,適合反向代理服務(wù)器有域名的情況,對于沒有域名的情況,雖然瀏覽器收到的Response中有正確的Cookie信息(從Chrom開發(fā)工具的Network頁簽查看,包括域名也已經(jīng)經(jīng)過轉(zhuǎn)換成反向代理的域名),但是瀏覽器卻沒能正常保存這個Cookie(從Chrom開發(fā)工具的Application頁簽查看Cookie)。這一點比較奇怪,Java寫的程序,通過反向代理后,不論反向代理是IP還是域名,瀏覽器端都可以正常拿到Cookie并保存,具體原因還沒搞清。不知是否Domino服務(wù)器是否有什么特別的安全設(shè)置。
解決方案:
在Domino服務(wù)器所在的內(nèi)網(wǎng),增加另一臺Java服務(wù)器,經(jīng)過反向代理的請求,先發(fā)給這臺Java服務(wù)器,由這臺Java服務(wù)器將Request轉(zhuǎn)發(fā)至Domino,收到Domino的Response之后,抽取Cookie,并進行設(shè)置,以保證返回給瀏覽器的Cookie能被保存。
至此,服務(wù)器部分問題解決。
補充說明:
“問題5”中,開始的解決方案,是Java服務(wù)器將拿到的Cookie通過Response的Body返回,由頁面JS將Cookie寫入。但是這種方案,當(dāng)頁面位于服務(wù)端時有效(跨域一樣有效),但是對于通過Electron打包的本地頁面,JS無法將Cookie正常寫入,這一點也暫時原因不明,不知道是否是由于瀏覽器認為本地頁面寫的Cookie與服務(wù)端跨域?對于本地頁面,還是需要服務(wù)端在Response中正常返回Cookie。
問題6:iOS版集成Cordova后,通過本地頁面訪問服務(wù)器,收到的Cookie不能正常保存,但是直接使用Cordova打包是可以的。
解決方案:
發(fā)現(xiàn)Cordova直接打包的應(yīng)用,AppDelegate繼承自原來的CDVAppDelegate,這個類初始化時執(zhí)行了:
?
NSHTTPCookieStorage* cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];[cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];int cacheSizeMemory = 8 * 1024 * 1024; // 8MBint cacheSizeDisk = 32 * 1024 * 1024; // 32MBNSURLCache* sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];[NSURLCache setSharedURLCache:sharedCache];將這部分代碼加入自己應(yīng)用的初始化部分即可。
nginx.conf 完整配置
?
location /myapp {add_header 'Access-Control-Allow-Origin' '*';add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';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_set_header Cookie $http_cookie;proxy_pass http://domino.server/;proxy_cookie_domain domino.server nginx.server;proxy_redirect off; }?
總結(jié)
以上是生活随笔為你收集整理的Nginx 反向代理及 Cookie 相关问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 同域名下不同端口cookie问题
- 下一篇: Android: Bundle机制