Closed roc2539 closed 6 years ago
Translation of this issue:
This is the case.
The front end uses antd pro, the back end egg. Front-end and back-end cross-domain.
The front end sets the proxy in .webpackrc.js, requests the backend egg, and returns "message": "missing csrf token". Request thinkjs normal.
Then set cors in egg again
Set in config.default.js
Config.security = {
// xframe: {
// enable: false,
// },
// csrf: {
// // enable: true,
// ignoreJSON: false, // defaults to false, when set to true, all requests with content-type of application/json
will be ignored
// useSession: true, // defaults to false, when set to true, csrf token will be saved to Session
// cookieName: 'csrfToken', // field name in cookie, default is csrfToken
// sessionName: 'csrfToken', // The field name in the Session, the default is csrfToken
// headerName: 'x-csrf-token', // passing the CSRF token's default field via header to x-csrf-token
// },
// whitelist
domainWhiteList: ['http://localhost:8000'],
};
Config.cors = {
Origin:'http://localhost:8000',
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS',
domainWhiteList: ['http://localhost:8000'],
};
Plugin.js, there are still problems. Exports.cors = { Enable: true, Package: 'egg-cors', }; // exports.security = { // domainWhiteList: [ 'http://localhost:8000' ], // };
Finally try to walk crsf, reference Https://eggjs.org/en-us/core/security.html#ajax-request Https://github.com/eggjs/egg-security#using-csrf-when-request-by-ajax The client reads the cookie and sets it in the header Request returns. POST /api2/login HTTP/1.1 Host: localhost:8000 Connection: keep-alive Content-Length: 0 Accept: application/json Origin: http://localhost:8000 X-csrf-token: D5Usnww2sbu4V-BN9QRrtlfI User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36 Content-type: application/json; charset=utf-8 Referer: http://localhost:8000/ Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.8,en;q=0.6 Cookie: csrfToken=D5Usnww2sbu4V-BN9QRrtlfI There is no problem in this case.
However, when the front-end and back-end interact. The first interaction, when the backend does not write a cookie. It will still appear "message": "missing csrf token". How to deal with?
In addition, if the configuration to csrfToken in the session, the front end, const csrfToken = sessionStorage.getItem ('csrfToken'); access to data. How to get it? Configure the session's httpOnly: false, or not.
最后,我目前的解决办法只有,
csrf: {
ignoreJSON: true, // 默认为 false,当设置为 true 时,将会放过所有 content-type 为 application/json
的请求
},
可以完全解决,可是这样是不是就不安全了,没有了CSRF的校验机制。 然后还没尝试,在生产环境的校验问题。
如果是跨域请求,就不要开 CSRF 的校验了。用 referer 来做防范吧
https://eggjs.org/zh-cn/basics/controller.html#referrer-校验 ? jsonp 配置? @dead-horse
那我现在就是,关闭csrf, srf: { enable: false, },
然后配置了, exports.jsonp = { whiteList: /^http?:\/\/localhost:8000\//, };
目前来说是OK的
那是这样设置吗
怎么我没有效果呢
情况是这样的。 前端用的的是antd pro,后端egg。前后端跨域。 前端在.webpackrc.js设置了 proxy,请求后端egg,返回"message": "missing csrf token"。请求thinkjs正常。 然后再egg中设置了 cors config.default.js中设置 config.security = { // xframe: { // enable: false, // }, // csrf: { // // enable: true, // ignoreJSON: false, // 默认为 false,当设置为 true 时,将会放过所有 content-type 为
application/json
的请求 // useSession: true, // 默认为 false,当设置为 true 时,将会把 csrf token 保存到 Session 中 // cookieName: 'csrfToken', // Cookie 中的字段名,默认为 csrfToken // sessionName: 'csrfToken', // Session 中的字段名,默认为 csrfToken // headerName: 'x-csrf-token', // 通过 header 传递 CSRF token 的默认字段为 x-csrf-token // }, // 白名单 domainWhiteList: ['http://localhost:8000'], }; config.cors = { origin:'http://localhost:8000', allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS', domainWhiteList: ['http://localhost:8000'], };plugin.js,依然有问题。 exports.cors = { enable: true, package: 'egg-cors', }; // exports.security = { // domainWhiteList: [ 'http://localhost:8000' ], // };
最后尝试走crsf,参考 https://eggjs.org/zh-cn/core/security.html#ajax-请求 https://github.com/eggjs/egg-security#using-csrf-when-request-by-ajax 客户端读取到了cookie,然后设置到Header中 Request 返回。 POST /api2/login HTTP/1.1 Host: localhost:8000 Connection: keep-alive Content-Length: 0 accept: application/json Origin: http://localhost:8000 x-csrf-token: D5Usnww2sbu4V-BN9QRrtlfI User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36 content-type: application/json; charset=utf-8 Referer: http://localhost:8000/ Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.8,en;q=0.6 Cookie: csrfToken=D5Usnww2sbu4V-BN9QRrtlfI 这种情况下没有问题了。
但是,前后端交互的时候。第一次交互,后端没有写cookie的时候。就还是会出现"message": "missing csrf token"。怎么处理?
另外,如果配置到csrfToken在session中,前端用, const csrfToken = sessionStorage.getItem('csrfToken');获取不到数据。要怎么获取?配置了session的 httpOnly: false,还是不行。