无法使用 Flask-JWT-Extended、React 和 Axios 在 Chrome 中设置 cookie
Unable to set cookies in Chrome using Flask-JWT-Extended, React, and Axios
背景和问题
我在 localhost:5000 有一个 Flask back-end 运行,在 localhost:3000 有一个 React SPA 运行。
我能够让他们说话但是当试图将 Flask 生成的令牌存储到浏览器的 cookie 中时 1) 响应 headers 在成功 POST 后执行 console.log(response)
时不包含任何 cookie axios
和 2) 未设置 cookie。但是当检查网络 > Login.js header 时,我实际上可以看到 Set-Cookie
键作为响应的 header 存在。我尝试了 Google 和 Whosebug 的多种解决方案,但似乎没有解决方案在这里工作,我真的无法弄清楚请求成功发出时发生了什么,Chrome 允许第三个方软件设置 cookie。甚至我也可以从 Network > Login.js header.
中看到令牌
步数
1) 用户输入用户名和密码并点击登录。
2) Axios POST 调用 Flask 的 back-end.
3) 处理数据并生成几个标记并将它们设置到 cookie 中。
4) 浏览器的 cookie 设置了很少的标记。 <- 这部分不工作。
代码
Flask back-end 使用 flask-jwt-extended
生成令牌
# app_config related to flask-jwt-extended
CORS_HEADERS = "Content-Type"
JWT_TOKEN_LOCATION = ["cookies"]
JWT_COOKIE_SECURE = False
JWT_COOKIE_CSRF_PROTECT = True
# post method from flask-restful for LoginAPI class
def post(self):
email = request.json.get("email")
password = request.json.get("password")
# some processing here.....
payload = {
"email": email
}
access_token = create_access_token(identity=payload)
refresh_token = create_refresh_token(identity=payload)
response = jsonify({"status": True})
set_access_cookies(response, access_token)
set_refresh_cookies(response, refresh_token)
return response
CORS 使用 flask-cors
# in below code, I had some issues with putting wildcard (*) into origin, so I've specified to the React SPA's host and port.
CORS(authentication_blueprint, resources={r"/authentication/*": {"origins": "http://localhost:3000"}},
supports_credentials=True)
React SPA - 使用 axios
进行 post 调用
# also tried `axios.defaults.withCredentials = true;` but same result.
export const login = (email, password, cookies) => {
return dispatch => {
const authData = {
email: email,
password: password
};
let url = 'http://127.0.0.1:5000/authentication/login/';
axios.post(url, authData, {withCredentials: true)
.then(
response => {
console.log(response)
})
.catch(err => {
console.log(err)
});
dispatch(authSuccess(email, password));
}
};
下图是在 axios
. 中成功调用 post 的响应
我不确定这是否正常,但响应的 header 没有显示我从 back-end.
设置的任何 cookie
下图来自网络 > header for login/
如图,用Set-Cookie
键可以清楚的看到token信息。我还检查过它们不是 secure
.
最后,当我从“应用程序”>“cookie”中查看我的 cookie 选项卡时,我什么也没看到。
所以问题来自 localhost
。
I have a Flask back-end running in localhost:5000 and a React SPA running on localhost:3000.
根据上面的陈述,非常具体地说,我是 运行 localhost:5000 的后端和 运行 127.0.0.1:3000 的 React SPA。
一旦我将 127.0.0.1
更改为 localhost
,它就像一个魅力。
还有一个旁注,在玩过 CORS
之后,我认为使用 Nginx
和 proxy_pass
将来自 React SPA 的请求传递给会容易得多后端避免完全使用 CORS
,因为如果必须在不同的环境(如测试、暂存等)中使用 CORS
,则必须在Web 服务器级别,例如)Nginx
无论如何,它需要的配置与我为本地环境设置的配置略有不同。
背景和问题
我在 localhost:5000 有一个 Flask back-end 运行,在 localhost:3000 有一个 React SPA 运行。
我能够让他们说话但是当试图将 Flask 生成的令牌存储到浏览器的 cookie 中时 1) 响应 headers 在成功 POST 后执行 console.log(response)
时不包含任何 cookie axios
和 2) 未设置 cookie。但是当检查网络 > Login.js header 时,我实际上可以看到 Set-Cookie
键作为响应的 header 存在。我尝试了 Google 和 Whosebug 的多种解决方案,但似乎没有解决方案在这里工作,我真的无法弄清楚请求成功发出时发生了什么,Chrome 允许第三个方软件设置 cookie。甚至我也可以从 Network > Login.js header.
步数
1) 用户输入用户名和密码并点击登录。
2) Axios POST 调用 Flask 的 back-end.
3) 处理数据并生成几个标记并将它们设置到 cookie 中。
4) 浏览器的 cookie 设置了很少的标记。 <- 这部分不工作。
代码
Flask back-end 使用 flask-jwt-extended
# app_config related to flask-jwt-extended
CORS_HEADERS = "Content-Type"
JWT_TOKEN_LOCATION = ["cookies"]
JWT_COOKIE_SECURE = False
JWT_COOKIE_CSRF_PROTECT = True
# post method from flask-restful for LoginAPI class
def post(self):
email = request.json.get("email")
password = request.json.get("password")
# some processing here.....
payload = {
"email": email
}
access_token = create_access_token(identity=payload)
refresh_token = create_refresh_token(identity=payload)
response = jsonify({"status": True})
set_access_cookies(response, access_token)
set_refresh_cookies(response, refresh_token)
return response
CORS 使用 flask-cors
# in below code, I had some issues with putting wildcard (*) into origin, so I've specified to the React SPA's host and port.
CORS(authentication_blueprint, resources={r"/authentication/*": {"origins": "http://localhost:3000"}},
supports_credentials=True)
React SPA - 使用 axios
# also tried `axios.defaults.withCredentials = true;` but same result.
export const login = (email, password, cookies) => {
return dispatch => {
const authData = {
email: email,
password: password
};
let url = 'http://127.0.0.1:5000/authentication/login/';
axios.post(url, authData, {withCredentials: true)
.then(
response => {
console.log(response)
})
.catch(err => {
console.log(err)
});
dispatch(authSuccess(email, password));
}
};
下图是在 axios
. 中成功调用 post 的响应
我不确定这是否正常,但响应的 header 没有显示我从 back-end.
下图来自网络 > header for login/
如图,用Set-Cookie
键可以清楚的看到token信息。我还检查过它们不是 secure
.
最后,当我从“应用程序”>“cookie”中查看我的 cookie 选项卡时,我什么也没看到。
所以问题来自 localhost
。
I have a Flask back-end running in localhost:5000 and a React SPA running on localhost:3000.
根据上面的陈述,非常具体地说,我是 运行 localhost:5000 的后端和 运行 127.0.0.1:3000 的 React SPA。
一旦我将 127.0.0.1
更改为 localhost
,它就像一个魅力。
还有一个旁注,在玩过 CORS
之后,我认为使用 Nginx
和 proxy_pass
将来自 React SPA 的请求传递给会容易得多后端避免完全使用 CORS
,因为如果必须在不同的环境(如测试、暂存等)中使用 CORS
,则必须在Web 服务器级别,例如)Nginx
无论如何,它需要的配置与我为本地环境设置的配置略有不同。