Vue Axios (CORS) 的问题 sending/storing 会话 cookie

Problem sending/storing session cookie with Vue Axios (CORS)

出于某种原因,我无法存储来自我的 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)

这是正在发生的事情。你发送一个 post 请求登录,你的服务器创建一个会话并在客户端上设置一个 cookie,但在你的情况下,客户端不是浏览器而是 xhr 对象(由 axios 创建),它很快就会被清除,因此您的浏览器不知道该会话,因此它不会保存 sessionId,因此没有凭据可以与未来的请求一起发送。
要解决这个问题,您有以下选择。

  1. 尝试按原样提交表单,不使用 axios 或任何 javascript。在您的表单上设置 method="post"action="<url_to_login_endpoint> 属性,让它变得疯狂。您的提交将由浏览器处理并保存 sessionID。
  2. 为您的后端研究基于令牌的身份验证(我不知道 flask,所以我不知道它是如何工作的),这将是一个完整的 SPA 和无状态解决方案。

我不知道业务逻辑和约束,但我建议设置 Token Auth,因为我认为这是理想且更安全的,但如果您只是一起破解它,请选择选项 1

所以在 Vue on front-end 你需要设置参数 withCredentials true
使用 axios axios.get("http://localhost:8081/shop/hello",{withCredentials:true})

在您的 server-side API 上,您需要启用 CORS 并将 header Access-Control-Allow-Credentials 添加到 HttpResponse,就像这样 Access-Control-Allow-Credentials=true

关于通过 CORS 设置 Cookie 的事情是它们需要由浏览器使用 Set-Cookie header 属性正确创建,您需要添加所有属性,否则它不会被创建. 我在创建 Vue.js & Spring-Boot 应用程序时遇到了同样的问题。

这就是我在 Java 中创建 Cookie 服务器端的方式,但您可以手动创建它或使用您使用的任何语言创建它,

因此,如果 Set-Cookie header 没有设置属性或无效,浏览器可能会出现无法正确创建 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);

这是我的服务器响应 Header 所以你可以看到它在浏览器中的样子,我在这里使用 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