Play如何发送CSRF令牌?

时间:2018-03-11 21:26:18

标签: playframework-2.6

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

我的用户界面是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 all获取requests that accept HTML, if a token isn’t already available in the incoming request. - 但我没有看到此令牌以回应我的初始GET请求。

由于我的UI(以及形式)不是播放用户界面,我无法使用play的注释在表单中添加csrf标记。我希望当主页发送时,播放会发送csrf令牌,Angular应用可以存储并稍后使用。

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

回复标题

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

请求标题(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响应中发送。

1 个答案:

答案 0 :(得分:2)

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

如果未配置tokencookieheadercsrf属性,则默认值为csrfToken用于令牌名称),没有任何内容已配置为Cookie,Csrf-Tokenheader

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

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

的Cookie

现在,如果只配置了cookie.name但没有配置头名称,则Play预计来自客户端的请求将包含头csrf中的Csrf-Token令牌(默认头名称)

Angular中接受cookie和返回标头的代码是

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

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

Angular中接受cookie和返回标头的代码是

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

请注意,对于Angular部分,url必须是相对的。请参阅此angular4 httpclient csrf does not send x-xsrf-token