我有一组 API ,每个都是 BaseRequestHandler 的子类。在 BaseRequestHandler 中,我将设置一个 self.user 变量,其中包含一个包含所有用户凭据作为值的字典。
例如:
self.user = {
"id": 0,
"ip": "user ip",
"country_name": "user country name",
...
}
我的问题是,如果对我的一组API的第一个传入请求未完成,则对另一个API的第二个传入请求将覆盖用户凭据,因此我不匹配当我需要使用这些凭据时,用户在第一个传入请求中的凭据。
换句话说,在第一个请求中,我拥有第二个传入请求的用户凭据。
如何跟踪每个传入的请求以避免用户的凭据不匹配?
你有什么建议吗?
提前致谢!
修改
在我们的项目中,我们有多个子类,我们已经实现了异步多处理Web服务器。
在Application
实例中,我们有一个这样的API列表:
application = tornado.web.Application([
(r"/api1/info1", api1.InfoOneRequestHandler),
(r"/api1/info2", api1.InfoTwoRequestHandler),
(r"/api2/info1", api2.InfoOneRequestHandler),
(r"/api3/info1", api3.InfoOneRequestHandler)
])
这些公开的API中的每一个都是子类,对于每一个API,我们都有一个名为BaseAPIOneRequestHandler
,BaseAPITwoRequestHandler
,BaseAPIThreeRequestHandler
的特定超类。
这些超类(BaseAPIOneRequestHandler
,APITwoBaseRequestHandler
,BaseAPIThreeRequestHandler
)也是子类,它们都继承了名为BaseAPIRequestHandler
的主(共享)超类。
BaseAPIRequestHandler
包含一种方法,用于检索调用该特定API的特定User Id
的权限和权限。
@tornado.gen.coroutine
def _retrieve_user_info(self, user_id):
self.user["id"] = ...
self.user["country_name"] = ...
self.user["country_code"] = ...
... POPULATE DATA ...
在每个子类(BaseAPIOneRequestHandler
,BaseAPITwoRequestHandler
,BaseAPIThreeRequestHandler
)中,我们称之为方法:
_request = tornado.escape.json_decode(self.request.body)
yield self._retrieve_user_info(_request["user_id"])
逻辑或多或少如下:
application = tornado.web.Application([
(r"/api1/info1", api1.InfoOneRequestHandler),
(r"/api1/info2", api1.InfoTwoRequestHandler),
(r"/api2/info1", api2.InfoOneRequestHandler),
(r"/api3/info1", api3.InfoOneRequestHandler)
])
class InfoOneRequestHandler(BaseAPIOneRequestHandler):
@tornado.gen.coroutine
def post(self, *args, **kwargs):
"""
The problem occurs within this method when we're going to
retrieve information about the user.
"""
... PERFORM OTHER INSTRUCTIONS ...
# _id variable will contain the ID of the user who's calling
# another API (it override the key "id" of the user
# who's calling the first API).
# When two users are calling two different APIs, both "id"
# keys will contain the ID of second user
_id = self.user["id"]
... REMAINING OPERATIONS ...
class BaseAPIOneRequestHandler(BaseAPIRequestHandler):
@tornado.gen.coroutine
def prepare(self):
"""
Here we're going to call the method to update the user's
credentials.
"""
super(BaseAPIOneRequestHandler, self).prepare()
... OTHER LOCAL THINGS ...
_request = tornado.escape.json_decode(self.request.body)
yield self._retrieve_user_info(_request["user_id"])
@tornado.gen.coroutine
def on_finish(self):
... API ONE LOCAL THINGS ...
super(BaseAPIOneRequestHandler, self).on_finish()
class BaseAPIRequestHandler(tornado.web.RequestHandler):
@tornado.gen.coroutine
def prepare(self):
... POPULATE GLOBAL DATA ...
@tornado.gen.coroutine
def get(self, *args, **kwargs):
self.write("Method not allowed")
@tornado.gen.coroutine
def _retrieve_user_info(self, user_id):
"""
Here we're going to update the user's information base on the
user's identifier (user_id).
"""
self.user["id"] = ...
self.user["country_name"] = ...
self.user["country_code"] = ...
... POPULATE USER DATA ...
@tornado.gen.coroutine
def options(self, *args, **kwargs):
self.set_header("Access-Control-Allow-Headers", self.request.headers["Access-Control-Request-Headers"])
self.set_header("Access-Control-Allow-Methods", self.request.headers["Access-Control-Request-Method"])
self.set_header("Access-Control-Allow-Origin", "*")
def on_finish(self):
self.user = None