【发布时间】:2021-09-24 15:39:05
【问题描述】:
我正在开发一个使用 Flask 服务器端和 Angular 客户端的网络应用程序。 我需要在这样的应用程序中允许多用户登录,并且我想使用烧瓶会话对象来处理登录会话,但是会话在请求之间以及每次被销毁时都不会持久化。
我已经采用了一些解决方法(通过向请求和响应中添加特定的标头,flask_cors 已配置并正常工作)。
有什么建议吗?
谢谢:)
编辑:
这是我的 CORS 初始化
CORS(app, supports_credentials=True, resources=r'/*')
我用来填充会话对象的登录方法定义如下:
@app.route('/login', methods=['POST', 'GET'])
def login():
print(request.headers)
_json = request.json
name = _json['username']
password = _json['password']
if name and password:
m = hashlib.md5(password.encode('utf-8')).hexdigest()
results = User.query.filter_by(username=name).first()
if m == results.password:
resp = jsonify("User logged in")
resp.status_code = 200
addRespHeaders(resp)
session.permanent = True
session['username'] = results.username
session['role'] = results.role
session.modified = True
print(session['username'], session['role'])
print(resp.headers)
return resp
else:
resp = jsonify("Attention! Wrong Password")
resp.status_code = 404
addRespHeaders(resp)
return resp
else:
resp = jsonify("Please enter the required fields")
resp.status_code = 404
addRespHeaders(resp)
return resp
最后是 addRespHeaders(resp) 方法:
def addRespHeaders(resp):
resp.headers.add('Access-Control-Allow-Headers', "Origin, Content-Type, X-Requested-With, Accept, x-auth")
resp.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
当我调用登录方法并尝试打印session['username'] 或session['role'] 时,它会打印出正确的值,但如果使用另一种方法,例如:
@app.route('/user/getLoggedIn', methods=['GET'])
def getLoggedInUser():
print('username' in session)
logged_data = UserPersistence.query.all()[0].username
logged_user = User.query.filter_by(username=logged_data).first()
schema = UserSchema()
resp = jsonify(schema.dump(logged_user))
resp.status_code = 200
addRespHeaders(resp)
return resp
print('username' in session) 返回False。
编辑2:
这是我的服务执行请求的样子:
const httpOptions = {
withCredentials: true,
headers: new HttpHeaders({'Content-Type': 'application/json'})
};
@Injectable({providedIn: 'root'})
export class UserService{
private userUrl = "http://192.168.0.88:5000";
constructor(private http: HttpClient){ }
/** GET users from server */
getUsers(): Observable<User[]>{
return this.http.get<User[]>(this.userUrl + '/users');
}
/** GET user by id. Will 404 if not found */
getUser(id: number): Observable<any>{
const url = `${this.userUrl}/user/${id}`;
return this.http.get<User>(url);
}
getLoggedInUser(): Observable<User>{
const url= `${this.userUrl}/user/getLoggedIn`;
return this.http.get<User>(url);
}
/** POST: login user */
login(username: string, password: string) {
return this.http.post(this.userUrl + '/login', JSON.stringify({"username": username, "password": password}), httpOptions);
}
/** POST: logout logged in user */
logout() {
return this.http.post(this.userUrl + '/logout', httpOptions);
}
/** POST: add a new user to the server */
addUser(user: User) {
return this.http.post(this.userUrl + '/user/add', user, httpOptions);
}
/** PUT: update the user on the server */
updateUser(user: User): Observable<any> {
return this.http.put(this.userUrl + '/user/update', user, httpOptions);
}
/** PUT: update user password */
updatePassword(user: PasswordReset): Observable<any> {
return this.http.put(this.userUrl + '/user/changePassword', user, httpOptions);
}
/** DELETE: delete the user from the server */
deleteUser(user: User | number) {
const id = typeof user == 'number' ? user : user.id;
const url = `${this.userUrl}/user/delete/${id}`;
return this.http.delete(url, httpOptions);
}
}
据我所知,withCredentials: true 应该包含凭据。
编辑3:
当我在本地主机中时,我设法在请求之间保持会话数据:
session_cookie = SecureCookieSessionInterface().get_signing_serializer(app)
@app.after_request
def after_request(response):
origin = request.headers.get('Origin')
if request.method == 'OPTIONS':
response.headers.add('Access-Control-Allow-Credentials', 'true')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
response.headers.add('Access-Control-Allow-Headers', 'x-csrf-token')
response.headers.add('Access-Control-Allow-Methods',
'GET, POST, OPTIONS, PUT, PATCH, DELETE')
if origin:
response.headers.add('Access-Control-Allow-Origin', origin)
else:
response.headers.add('Access-Control-Allow-Credentials', 'true')
if origin:
response.headers.add('Access-Control-Allow-Origin', origin)
same_cookie = session_cookie.dumps(dict(session))
response.headers.add("Set-Cookie", f"{same_cookie}; Secure; HttpOnly; SameSite=None; Path=/;")
return response
现在的问题是,如果我尝试登录同一网络下的另一台 PC,所有请求都会被阻止,因为请求之间没有传递 cookie。 任何想法?谢谢
【问题讨论】:
标签: angular multi-user flask-session