How to set 'secure' and 'httponly' cookie in Tornado?
cookies, python, tornado
Solution
The issue is not with Tornado or Python, but with my server as I was not using HTTPS:
A secure cookie has the secure attribute enabled and is only used via HTTPS, ensuring that the cookie is always encrypted when transmitting from client to server. This makes the cookie less likely to be exposed to cookie theft via eavesdropping. In addition to that, all cookies are subject to browser's same-origin policy.
Problem
I have a Tornado app which uses Google Oauth 2.0 Authentication, gets the email and sets that in a cookie. Now I don't want anyone else to access this cookie, copy the value and get another user's details on my app. So I want to make this cookie `httponly` and `secure` cookie. However when I pass these as arguments its not able to set the cookie: ``` self.set_secure_cookie('trakr', email, secure=True, httponly=True) ``` I am suing Tornado 3.2.2 and Python 2.7.5. since its not able to set the cookie, it keeps redirecting to google auth page. Here is my code: ``` class GAuthLoginHandler(BaseHandler, tornado.auth.GoogleOAuth2Mixin): @tornado.gen.coroutine def get(self): if self.get_current_user(): self.redirect('/products') return if self.get_argument('code', False): user = yield self.get_authenticated_user(redirect_uri=settings.google_redirect_url, code=self.get_argument('code')) if not user: self.clear_all_cookies() raise tornado.web.HTTPError(500, 'Google authentication failed') access_token = str(user['access_token']) http_client = self.get_auth_http_client() response = yield http_client.fetch('https://www.googleapis.com/oauth2/v1/userinfo?access_token='+access_token) user = json.loads(response.body) self.set_secure_cookie('trakr', user['email'], secure=True, httponly=True) self.redirect(self.get_argument("next", "/products")) return elif self.get_secure_cookie('trakr'): self.redirect('/products') return else: yield self.authorize_redirect( redirect_uri=settings.google_redirect_url, client_id=self.settings['google_oauth']['key'], scope=['email'], response_type='code', extra_params={'approval_prompt': 'auto'}) ``` The code works perfectly fine when I remove `secure` and `httponly` arguments. It also works if I just send `httponly` argument, however it doesn't seem to set the cookie when I pass both the arguments. Am I doing something wrong?