Ikr*_*rom 3 cookies nginx playframework
我正在使用playframework和nginx.playframework可以将以下cookie添加到http响应:PLAY_SESSION,PLAY_FLASH,PLAY_LANG.
我想确保在nginx级别只允许上面的cookie(PLAY_*).如果有其他cookie(假设它们被意外添加),则应该通过nginx删除它们.
如何在nginx中仅允许http响应中的预定义cookie?
PS:如果在nginx中无法解决这个问题,我需要使用playframework进行修复.
首先,让我们确定一下什么是cookie - 它们是一些"粘性"隐藏信息,可以让你在给定用户代理的网站上保持状态.这些cookie通常用于跟踪用户,保持会话和存储网站的次要偏好信息.
Set-Cookie HTTP响应头(从服务器到客户端)Cookie可以由服务器通过Set-Cookie响应标头设置(每个cookie都有一个单独的标头),或者在页面已经从服务器传输到客户端之后通过JavaScript设置.
请注意,设置cookie是一项非常复杂的工作 - 它们具有到期日期,http/https设置,路径等 - 因此显然有必要Set-Cookie为每个cookie 使用单独的标头.
这个具有单独标头的要求通常不是问题,因为cookie不应该经常被修改,因为它们通常存储非常小的信息,例如会话标识符,其中重载信息存储在关联的中.服务器上的数据库.
Cookie HTTP请求标头(从客户端到服务器)无论首次设置如何,cookie都将包含在客户端使用Cookie请求标头对服务器的合格后续请求中,并在一个标头中包含一系列符合条件的cookie.
请注意,这样,客户端发送回服务器的这些cookie是一个简单的名称和属性对列表,没有任何关于在客户端存储这些属性的基础cookie的额外信息(例如,到期日期) ,http/https设置和路径由客户端内部保存,但未在后续的服务器请求中显示).
Cookie请求标头字段的这种简洁性很重要,因为一旦设置,符合条件的cookie将随后包含在所有即将发布的具有合格方案/域/路径组合的所有资源的请求中.
使用cookie的常见问题,特别是在加速和nginx的上下文中,是:
默认情况下,cookie使缓存无效(例如,除非您使用proxy_ignore_headers Set-Cookie;),
或者,如果您进行草率配置,cookie可能会破坏您的缓存
例如,通过客户端能够在没有的情况下将cookie传递给上游proxy_set_header Cookie "";,
或者,通过服务器坚持在没有的情况下设置cookie proxy_hide_header Set-Cookie;.
Cookie 来自客户请注意,nginx支持查看客户端Cookie通过该$cookie_name方案发送给它的cookie(在请求标头中).
如果您希望将客户端限制为仅发送某些cookie,您可以Cookie根据这些变量轻松地重新构建标头,并仅向上游发送您想要的任何一个(proxy_set_header如上所述).
或者,您甚至可以根据cookie做出决定,以决定向哪个上游发送请求,或者为每个用户/每个会话proxy_cache_key做出决定,或者根据cookie做出访问控制决策.
Set-Cookie 从后端至于上游发送回cookie,您当然可以决定阻止所有内容以显着改善缓存特性(如果适用于您的应用程序或其部分),或者使用proxy_cookie_domain和/ 修复域和/或路径或者proxy_cookie_path分别.
否则,做出任何其他路由决定通常为时已晚 - 请求已由所选上游服务器处理,并且响应已准备好提供 - 因此,自然地,似乎没有办法这些单独的Set-Cookiecookie通过nginx中的常规方式(除非您想要使用第三方模块,或lua或perl),因为对已完成的请求做出任何重要的路由决策已经太晚了.
基本上,这些Set-Cookiecookie更多地与内容有关,而不是与服务或路由的方式有关,因此,通过nginx集成功能来查看它们似乎不合适.
(如果您确实需要在请求完成后做出路由决策,那么nginx确实支持X-Accel-Redirect,以及一些其他特殊标头.)
如果您的问题是安全问题,那么,正如我上面所指出的那样,上游开发人员已经可以使用JavaScript来设置他们想要的任何额外的cookie,因此,有效地,尝试使用nginx来限制一些但不是全部的Set-Cookie响应来自服务器在现实世界中是一种毫无意义的努力(因为通过JavaScript设置的cookie之间几乎没有任何区别Set-Cookie).
您可以轻松地检查并重建Cookie客户端发送到服务器的标头,然后再将其传递给后端,并且只在请求中包含受制裁的cookie到上游后端,
但是,除非您想使用lua/perl,或者拥有自己的nginx模块(以及可能从您所服务的页面中隔离JavaScript),否则您不能仅将某些Set-Cookie标头从上游后端传递回客户端nginx.conf - 使用Set-Cookie标题,它是一个全有或全无的情况,并且似乎没有足够好的用例来实现独特的方法.
对于 Nginx 解决方案,可能值得在serverfault上询问。这是通过 Play Framework 的潜在解决方案。
package filters
import javax.inject._
import play.api.mvc._
import scala.concurrent.ExecutionContext
@Singleton
class ExampleFilter @Inject()(implicit ec: ExecutionContext) extends EssentialFilter {
override def apply(next: EssentialAction) = EssentialAction { request =>
next(request).map { result =>
val cookieWhitelist = List("PLAY_SESSION", "PLAY_FLASH", "PLAY_LANG")
val allCookies = result.newCookies.map(c => DiscardingCookie(c.name))
val onlyWhitelistedCookies = result.newCookies.filter(c => cookieWhitelist.contains(c.name))
result.discardingCookies(allCookies: _*).withCookies(onlyWhitelistedCookies: _*)
}
}
}
Run Code Online (Sandbox Code Playgroud)
该解决方案利用过滤器和Result操作。测试对性能的不利影响。
| 归档时间: |
|
| 查看次数: |
3247 次 |
| 最近记录: |