使用 Vue Axios (CORS) 发送/存储会话 cookie 时出现问题
Posted
技术标签:
【中文标题】使用 Vue Axios (CORS) 发送/存储会话 cookie 时出现问题【英文标题】:Problem sending/storing session cookie with Vue Axios (CORS) 【发布时间】:2020-11-08 16:23:10 【问题描述】:由于某种原因,我无法从我的 Flask 后端(端口 5000)存储会话 cookie,并通过 Axios 从我的 Vue 前端(端口 8082)将其作为凭据发送。我在前端创建了一个全局 axios,然后登录获取会话 cookie,然后尝试执行需要身份验证的请求。我看到 cookie 收到来自 /login 的响应,但是当发出下一个请求时它不包含它,导致 401。请求与 Postman 一起工作正常,所以我认为问题在于 CORS 以某种方式阻止发送凭据。
main.js(设置Axios的全局实例)
Vue.prototype.$http = Axios;
Vue.prototype.$http.defaults.withCredentials = true
auth.js(用于登录和获取 cookie 的 Vuex 模块)
this._vm.$http.post(backendUrl+'/api/login',
email: formEmail,
password: formPassword,
headers: 'Content-type': 'application/json'
)
.then(function (response)
console.log(response.data);
router.push('profile');
commit(types.UPDATE_AUTH_SIGN_USER_SUCCESS, response)
commit(types.UPDATE_AUTH_FORM_PASSWORD, '')
commit(types.UPDATE_AUTH_FORM_EMAIL, '')
commit(types.RESET_APP_LOADING)
)
Profile.Vue(要求会话 cookie 身份验证的请求不起作用,401)
this.$http.get(backendUrl+'/api/user/gdpr/fetch', function (response)
console.log(response);
if (response.data == 0)
context.dialogGDPR = true;
context.$store.commit(types.UPDATE_APP_IS_LOADING, false)
)
对于 Flask 后端,我使用以下方法激活 CORS:
app.py
CORS(app, origins='http://127.0.0.1:8082', supports_credentials=True)
app.config['CORS_HEADERS'] = 'Content-Type'
对于每个已定义的请求:
@cross_origin(origins='http://127.0.0.1:8082', supports_credentials=True)
【问题讨论】:
您能看到在应用程序选项卡中设置和更新的 cookie 吗?您是否也尝试过创建一个实例并将其添加到原型而不是完整的 axios 对象,就像这样。 ``` import axios from 'axios' const instance = axios.create( withCredentials: true ) Vue.prototype.$http = instance; ``` @HimanshuPant 我不明白如何使用应用程序选项卡,但我检查了存储选项卡,那里没有 cookie。我尝试使用您建议的实例,但仍然得到 401 并且没有会话 cookie。 我写了一篇关于在 CORS here 中使用 cookie 的常见问题解答条目,它可能会帮助您找到问题所在。同一站点上还有一个标头检查器,可以检查您的响应标头是否为 CORS 正确设置了 cookie。如果这没有帮助... 1. 您能否检查任何控制台错误/警告并将它们包含在问题中? 2. 你能说出你测试过的确切浏览器版本吗? 3. 您能否发布登录请求的响应标头,尤其是与 cookie 和 CORS 相关的标头? 【参考方案1】:这就是正在发生的事情。您发送一个登录请求,您的服务器创建一个会话并在客户端上设置一个 cookie,但在您的情况下,客户端不是浏览器,而是 xhr 对象(由 axios 创建),因此很快就会被清除您的浏览器不知道会话,因此它不会保存 sessionId,因此没有凭据可以与未来的请求一起发送。 要解决此问题,您有以下选择。
-
尝试按原样提交表单,而不使用 axios 或任何 javascript。在您的表单上设置
method="post"
和action="<url_to_login_endpoint>
属性,然后让它发疯。您的提交将由浏览器处理并保存 sessionID。
为您的后端研究基于令牌的身份验证(我不知道烧瓶,所以我不知道它是如何工作的),这将是一个完整的 SPA 和无状态解决方案。
我不知道业务逻辑和约束,但我建议设置 Token Auth,因为我认为这是理想且更安全的,但如果您只是一起破解它,请选择选项 1
【讨论】:
我认为会话 cookie 应该以某种方式与 axios 一起工作,否则为什么会有 withCredentials 选项? axios 对此没有解决方案似乎很奇怪。 withCredentials 是用于发送现有会话身份验证 cookie 的标志,而不是设置这些 cookie。不是真的 axios 而是 xhr【参考方案2】:所以在前端的Vue中你需要设置参数withCredentials
true
使用axios时axios.get("http://localhost:8081/shop/hello",withCredentials:true)
在您的服务器端 API 上,您需要启用 CORS 并将标头 Access-Control-Allow-Credentials
添加到 HttpResponse 中,例如 Access-Control-Allow-Credentials=true
在 CORS 上设置 Cookie 的问题是它们需要由浏览器使用 Set-Cookie
标头属性正确创建,您需要添加所有属性,否则不会创建。
我在创建 Vue.js 和 Spring-Boot 应用程序时遇到了同样的问题。
这就是我在 Java 中创建 Cookie 服务器端的方式,但您可以手动创建它,也可以使用您使用的任何语言创建它,
因此,如果Set-Cookie
标头未设置属性或无效,则浏览器无法正确创建 Cookie 可能会出现问题,至少这是我在短时间内发现的,但它对我有用.
我希望这会有所帮助。
Cookie cookie = new Cookie("NewRandomCookie",UUID.randomUUID());
cookie.setPath("/");
cookie.setMaxAge(3600);
c.setSecure(false);
c.setHttpOnly(true);
cookie.setDomain("localhost");
servletResponse.addCookie(c);
这是我的服务器响应标头,因此您可以看到它在浏览器中的外观,我在这里使用 Chrome。我认为您在这里看到的所有属性都是必需的,如果您设置属性“安全”并且您需要设置站点域以便之后访问 cookie,则不会设置 cookie。
Request Header
Request URL: http://localhost:8081/shop/hello
Request Method: GET
Status Code: 200
Remote Address: [::1]:8081
Referrer Policy: strict-origin-when-cross-origin
Response Header
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:8080
Connection: keep-alive
Content-Type: application/json
Date: Tue, 10 Nov 2020 23:10:30 GMT
Keep-Alive: timeout=60
Set-Cookie: JSESSIONID=6D1C6D23F775A1F650842E55AC0A6E3C; Path=/; HttpOnly
->
Set-Cookie: NewRandomCookie=0fdeba77-072d-4a87-9bc3-f041b2ef138a; Max-
Age=3600; Expires=True, 10-Nov-2020 23:47:32 GMT; Domain=localhost; Path=/;
HttpOnly;
<-
Transfer-Encoding: chunked
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
【讨论】:
以上是关于使用 Vue Axios (CORS) 发送/存储会话 cookie 时出现问题的主要内容,如果未能解决你的问题,请参考以下文章