Authentication using cookie key with asynchronous callback
- by greg
I need to write authentication function with asynchronous callback from
remote Auth API. Simple authentication with login is working well, but
authorization with cookie key, does not work. It should checks if in
cookies present key "lp_login", fetch API url like async and execute
on_response function.
The code almost works, but I see two problems. First, in on_response
function I need to setup secure cookie for authorized user on every
page. In code user_id returns correct ID, but line:
self.set_secure_cookie("user", user_id) does't work. Why it can be?
And second problem. During async fetch API url, user's page has loaded
before on_response setup cookie with key "user" and the page will has
an unauthorized section with link to login or sign on. It will be
confusing for users. To solve it, I can stop loading page for user who
trying to load first page of site. Is it possible to do and how? Maybe
the problem has more correct way to solve it?
class BaseHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get_current_user(self):
user_id = self.get_secure_cookie("user")
user_cookie = self.get_cookie("lp_login")
if user_id:
self.set_secure_cookie("user", user_id)
return Author.objects.get(id=int(user_id))
elif user_cookie:
url = urlparse("http://%s" % self.request.host)
domain = url.netloc.split(":")[0]
try:
username, hashed_password = urllib.unquote(user_cookie).rsplit(',',1)
except ValueError:
# check against malicious clients
return None
else:
url = "http://%s%s%s/%s/" % (domain, "/api/user/username/", username, hashed_password)
http = tornado.httpclient.AsyncHTTPClient()
http.fetch(url, callback=self.async_callback(self.on_response))
else:
return None
def on_response(self, response):
answer = tornado.escape.json_decode(response.body)
username = answer['username']
if answer["has_valid_credentials"]:
author = Author.objects.get(email=answer["email"])
user_id = str(author.id)
print user_id # It returns needed id
self.set_secure_cookie("user", user_id) # but session can's setup