Play 如何发送 CSRF 令牌?

how Play sends CSRF token?

当我的应用程序从服务器检索 index.html 和其他 jscss 文件时,我没有在 headers 中看到 csrf 标记或饼干。 play 如何发送 csrf 令牌?

我的 UI 是一个 Angular 应用程序,由 play 提供服务。从文档中,我了解到 csrf 令牌

This token gets placed either in the query string or body of every form submitted, and also gets placed in the user’s session

文档还说

To ensure that a CSRF token is available to be rendered in forms, and sent back to the client, the global filter will generate a new token for allGETrequests that accept HTML, if a token isn’t already available in the incoming request. - 但我没有看到此令牌响应我最初的 GET 请求。

由于我的 UI(以及表格)不是游戏 UI,我无法使用 play 的注释将 csrf 标记放入表格中。我希望在交付主页时,播放会发送 csrf 令牌,Angular 应用程序可以稍后存储和使用该令牌。

以下是我在浏览器的开发者控制台上看到的headers。

回应headers

Content-Length      1421
Content-Type        text/html; charset=UTF-8
Date        Sun, 11 Mar 2018 21:23:52 GMT
Referrer-Policy     origin-when-cross-origin, strict-origin-when-cross-origin
X-Content-Type-Options      nosniff
X-Frame-Options     DENY
X-Permitted-Cross-Domain-Policies       master-only
X-XSS-Protection        1; mode=block

请求headers (600 B)

Accept      text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
    Accept-Encoding     gzip, deflate
    Accept-Language     en-US,en;q=0.5
    Connection      keep-alive
    Cookie      PLAY_SESSION=eyJhbGciOiJIUzI1N…AR2uh5KwKBhqKxQQT1wWPWC2yPyCM
    Host        localhost:9000
    Upgrade-Insecure-Requests       1
    User-Agent      Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/58.0

播放中Action首页是哪个服务器

def index =
    Action { implicit request =>
      val Token(name, value) = CSRF.getToken.get
      println(s"Token name ${name}, value ${value}")
      Ok(views.html.index("Your new application is ready."))
    }

我可以看到(打印)令牌名称和值,但我不确定它是否在 Ok 响应中发送。

这是部分答案。 play 中感兴趣的 3 个 csrf 配置是 tokencookieheader names

如果配置 token 的 none、cookiecsrfheader 属性,则默认值为 csrfToken令牌名称),没有为 cookie 配置任何内容,为 header

配置 Csrf-Token

配置 token 名称后,play 似乎会发送一个 PLAY_SESSION cookie。例如 token.name = "CJCsrfToken"。在这种情况下,令牌的名称是 CJCsrfToken 而不是 csrfToken。但是,我找不到如何发送 csrfToken 以及如何在客户端检索它。我有一个 Angular5 客户端,当在 play.

中只配置了 token.name 时,我无法让它通过 csrf

如果配置了 cookie 名称,Play 会将 csrf 令牌存储在具有给定名称的 cookie 中,而不是 session。我想我们应该配置 token.namecookie.name。例如 cookie.name = "CJCsrfCookie" 表示您应该看到名称为 CJCsrfCookie

的 cookie

现在,如果只配置了 cookie.name 但没有配置 header 名称,那么 Play 预计来自客户端的请求将包含 header [=22] 中的 csrf 令牌=](默认header名称)

Angular 中用于接受 cookie 和 return header 的代码是

HttpClientXsrfModule.withOptions({ cookieName: 'CJCsrfCookie', headerName: 'Csrf-Token' }),

如果您不想使用默认的 header 名称,请在 header.name 中配置新名称。这将是从中接受 CSRF 令牌的 header 的名称。 例如 header.name = "CJCsrfHeader"

Angular 中用于接受 cookie 和 return header 的代码是

HttpClientXsrfModule.withOptions({ cookieName: 'CJCsrfCookie', headerName: 'CJCsrfHeader' }),

请注意,对于 Angular 部分,url 必须是相对的。看到这个 angular4 httpclient csrf does not send x-xsrf-token