我有一个在http://127.0.0.1:5000上运行的烧瓶服务器和一个在 http://localhost:8080 上运行的 vuejs 前端我已经制作了 api 并用邮递员对其进行了测试,一切都按预期工作:(
对 /login 的 POST 请求 -> 登录成功 -> 允许登录用户执行操作)。
但是当我从 vuejs(使用 axios)发送请求时,cookie 似乎不起作用(对 /login 的 POST 请求 -> 登录成功 -> 无法执行允许登录用户执行的操作(如果会话中的“登录”在烧瓶中为 False))。
烧瓶 API 代码:
app = Flask(__name__)
SESSION_TYPE = 'redis'
app.config.from_object(__name__)
app.config.from_mapping(
SECRET_KEY='dev'
)
app.config.update(SESSION_COOKIE_SAMESITE="None", SESSION_COOKIE_SECURE=True)
cross_origin(automatic_options=True)
app.config['CORS_HEADERS'] = 'Content-Type'
CORS(app, resources={r"/*": {"origins": "*"}},support_credentials=True)
## configure db
db = yaml.load(open('db.yaml'))
app.config['MYSQL_HOST'] = db['mysql_host']
app.config['MYSQL_USER'] = db['mysql_user']
app.config['MYSQL_PASSWORD'] = db['mysql_password']
app.config['MYSQL_DB'] = db['mysql_db']
mysql = MySQL(app)
## Homepage
@app.route('/index',methods=['GET'])
@cross_origin(supports_credentials=True,origin='http://localhost:8080/')
def index():
if 'loggedin' in session:
return jsonify({
"msg":"user is logged in",
"data":{
"username":session['username'],
"loggedin":True
},
"status":200
})
else:
return jsonify({
"msg":"user is not logged in",
"data":{
"username":None,
"loggedin":False
},
"status":200
})
## LOGIN
@app.route('/login',methods=['GET','POST'])
@cross_origin(supports_credentials=True,origin='http://localhost:8080/')
def login():
# print("initial check ",('loggedin' in session))
if request.method == 'POST':
req = request.get_json()
username = req['username']
password = req['password']
cur = mysql.connection.cursor()
if username == "" or password == "":
return jsonify({
'msg':'Username and password required',
'status':401
})
user = cur.execute('SELECT * FROM user WHERE username =%s',(username,))
userdetails = cur.fetchone()
if user <=0 or not check_password_hash(userdetails[1],password):
result = {
'msg':'Incorrect username or password',
'status':401
}
return jsonify(result)
else:
session.clear()
session['username'] = userdetails[0]
session['loggedin'] = True
## print("session username = ",session['username'])
result = {
'msg':"Successfully logged in",
'status':200
}
print("inside login <loggedin> = ",('loggedin' in session))
globallogin = True
globalusername = userdetails[0]
return jsonify(result)
## return redirect('/index')
return jsonify({
"msg":"get request at /login",
"status":200
})
登录.vue:
<template>
<div id = "login">
<h1>Login page</h1>
<label>Username</label>
<input type="text" v-model="username">
<label>Password</label>
<input type="password" v-model="password">
<button v-on:click="login()">Log in</button>
</div>
</template>
<script>
import axios from 'axios'
export default {
data: function(){
return{
username:"",
password:""
}
},
methods:{
resetform: function(){
this.username = ""
this.password = ""
return
},
login: function(){
const payload = {
username:this.username,
password:this.password
}
axios.post("http://127.0.0.1:5000/login",payload,{withCredentials: true})
.then( (data) =>{
console.log(data)
if(data.data.status == 401){
alert(data.data.msg)
this.resetform()
}
}).catch( (err) => {
console.log(err)
})
}
},
mounted() {
axios.get("http://127.0.0.1:5000/login")
.then((data)=>{
console.log(data);
})
}
}
</script>
索引.vue
<template>
<h1>Index page</h1>
</template>
<script>
import axios from 'axios'
export default {
mounted(){
axios.get('http://127.0.0.1:5000/index').then((data)=>{
console.log(data)
}).catch((err)=>{
console.log(err);
})
}
}
</script>
当我使用邮递员登录时,我得到响应successfully logged in,当我使用邮递员获取 url/index 时,我进入"user is logged in"但是response.data当我使用浏览器(chrome)从 vuejs 服务器登录时,我仍然进入"successfully logged in",response.data.msg但是当我转到 /index 时,我得到"user is not logged in".
我注意到的另一件事是,在登录请求之后的邮递员中有一个带有 cookie id 的 set-cookie 标头, Set-Cookie = session=77e40d54-066c-48a7-9b2b-88f36d9a3b86; HttpOnly; Path=/但是当我在标头字段中控制台记录来自 vuejs 的响应时,没有 set-cookie 标头(只有 application-type 和内容长度)