我的 React+Flask 应用程序中的会话(redis)有问题
I have problem with sessions(redis) in my React+Flask application
我有应用程序:后端烧瓶(api)和前端反应。程序在本地主机上运行良好,但在服务器(使用 apache)上部署后出现问题。
P.S。在 :80 端口上进行反应,在 :81 端口上进行烧瓶。
反应
加载页面时 - 使用 Effect 检查当前会话。
import React, {useEffect, useState} from 'react'
import { useNavigate } from 'react-router-dom';
export const Login = () => {
const [user, setUser] = useState(null)
useEffect(() => {
fetch('http://myip:81/api/@me').then(
res => res.json()
).then(
user => {
setUser(user)
}
)
}, [])
return(...)
}
登录:
import React, {useEffect, useState} from 'react'
import httpClient from "../components/httpClient"
export const LoginPage = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [userID, setUserID] = useState(null)
const [error, setError] = useState(false)
const logInUser = async () => {
try {
const res = await httpClient.post("http://myip:81/api/login", {
content: {
email,
password
}
})
setEmail('')
setPassword('')
window.location.href = `/profile`
} catch (e) {
if (e.response.status !== 200) {
setError(true)
setEmail('')
setPassword('')
}
}
}
return(...)
}
烧瓶API
正在检查当前用户:
@app.route("/api/@me")
def get_current_user():
user_id = session.get("user_id")
if not user_id:
return {"error": "Unauthorized"}, 401
user = User.query.filter_by(id=user_id).first()
return {'id': user.id, 'email': user.email}
登录:
@app.route('/api/login', methods=['POST'])
def login():
request_data = json.loads(request.data)["content"]
email = request_data["email"]
password = request_data["password"]
user = User.query.filter_by(email=email).first()
if user is None:
return {'error': 'User does not exist'}, 401
if not bcrypt.check_password_hash(user.password, password):
return {'error': 'Wrong password'}, 401
session["user_id"] = user.id
session["email"] = user.email
return {'id': user.id, 'email': user.email}, 200
Redis 检查
root@nik:~# redis-cli
127.0.0.1:6379> ping
PONG
当用户登录时,正确创建会话:
127.0.0.1:6379> keys *
1) "session:8e3f1576-8505-40c0-b8ba-bdb1a733133b"
2) "session:ce4f6024-c965-46c0-b0f6-cfafb87640df"
如果我在浏览器中输入 myip:81/api/@me - json 正确返回(就像会话运行良好),但如果我正在尝试它来自我的反应页面 - json 返回“未经授权”。
我做错了什么?有什么想法吗?
经过5天的网上冲浪,我找到了解决办法!
我注意到了这样一件事:
浏览器 ---(cookie)---> Flask 后端运行良好
浏览器 ---(cookie)---> React ---(无 cookie)---> Flask 因为没有对烧瓶做出反应的请求中的 cookie
所以我需要像这样更改我的代码:
import React, {useEffect, useState} from 'react'
import { useNavigate } from 'react-router-dom';
export const Login = () => {
const [user, setUser] = useState(null)
useEffect(() => {
fetch('http://myip:81/api/@me', {credentials: 'include'}).then(
res => res.json()
).then(
user => {
setUser(user)
}
)
}, [])
return(...)
}
我有应用程序:后端烧瓶(api)和前端反应。程序在本地主机上运行良好,但在服务器(使用 apache)上部署后出现问题。
P.S。在 :80 端口上进行反应,在 :81 端口上进行烧瓶。
反应
加载页面时 - 使用 Effect 检查当前会话。
import React, {useEffect, useState} from 'react'
import { useNavigate } from 'react-router-dom';
export const Login = () => {
const [user, setUser] = useState(null)
useEffect(() => {
fetch('http://myip:81/api/@me').then(
res => res.json()
).then(
user => {
setUser(user)
}
)
}, [])
return(...)
}
登录:
import React, {useEffect, useState} from 'react'
import httpClient from "../components/httpClient"
export const LoginPage = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [userID, setUserID] = useState(null)
const [error, setError] = useState(false)
const logInUser = async () => {
try {
const res = await httpClient.post("http://myip:81/api/login", {
content: {
email,
password
}
})
setEmail('')
setPassword('')
window.location.href = `/profile`
} catch (e) {
if (e.response.status !== 200) {
setError(true)
setEmail('')
setPassword('')
}
}
}
return(...)
}
烧瓶API
正在检查当前用户:
@app.route("/api/@me")
def get_current_user():
user_id = session.get("user_id")
if not user_id:
return {"error": "Unauthorized"}, 401
user = User.query.filter_by(id=user_id).first()
return {'id': user.id, 'email': user.email}
登录:
@app.route('/api/login', methods=['POST'])
def login():
request_data = json.loads(request.data)["content"]
email = request_data["email"]
password = request_data["password"]
user = User.query.filter_by(email=email).first()
if user is None:
return {'error': 'User does not exist'}, 401
if not bcrypt.check_password_hash(user.password, password):
return {'error': 'Wrong password'}, 401
session["user_id"] = user.id
session["email"] = user.email
return {'id': user.id, 'email': user.email}, 200
Redis 检查
root@nik:~# redis-cli
127.0.0.1:6379> ping
PONG
当用户登录时,正确创建会话:
127.0.0.1:6379> keys *
1) "session:8e3f1576-8505-40c0-b8ba-bdb1a733133b"
2) "session:ce4f6024-c965-46c0-b0f6-cfafb87640df"
如果我在浏览器中输入 myip:81/api/@me - json 正确返回(就像会话运行良好),但如果我正在尝试它来自我的反应页面 - json 返回“未经授权”。
我做错了什么?有什么想法吗?
经过5天的网上冲浪,我找到了解决办法!
我注意到了这样一件事:
浏览器 ---(cookie)---> Flask 后端运行良好
浏览器 ---(cookie)---> React ---(无 cookie)---> Flask 因为没有对烧瓶做出反应的请求中的 cookie
所以我需要像这样更改我的代码:
import React, {useEffect, useState} from 'react'
import { useNavigate } from 'react-router-dom';
export const Login = () => {
const [user, setUser] = useState(null)
useEffect(() => {
fetch('http://myip:81/api/@me', {credentials: 'include'}).then(
res => res.json()
).then(
user => {
setUser(user)
}
)
}, [])
return(...)
}