Search code examples
pythongoogle-app-enginecookieswebapp2webob

Webapp2 Python set_cookie does not support samesite cookie?


In webapp2 documentation there is no mention of setting the SameSite attribute for a cookie, it seems to be built on the response handler from WebOB, I checked webOB doc page it clearly shows the 'SameSite' flag as an accepted cookie parameter

I tried to set it nonetheless in set cookie:

self.response.set_cookie(name, secure_cookie, path='/', secure=True,
httponly=True, samesite='lax', expires=expireDate)

But I received the below error:

TypeError: set_cookie() got an unexpected keyword argument 'samesite'

I know one can use self.response.headers.add_header('Set-Cookie', ... but I was hoping I could use self.response.set_cookie following the webapp2 documentation


Solution

  • Samesite was introduced in webob 1.8 but The App Engine Standard Environment SDK ships with 1.1.1 and 1.2.3 as built-in libraries.

    You could try vendoring in a more recent webob to see if this overrides the built-in version.

    Once a version of webob that supports samesite is installed, a samesite keyword argument can be passed to Response.set_cookie

    class MyHandler(webapp2.RequestHandler):
        def get(self):
            self.response.set_cookie('cookie-name', value='42', samesite='lax')
    

    This sample app sets samesite=strict on the session cookie generated by webapp2_extras.sessions, assuming the underlying webob package supports it.

    import webapp2
    from webapp2_extras import sessions
    
    
    class HelloHandler(webapp2.RequestHandler):
        def dispatch(self):
            self.session_store = sessions.get_store(request=self.request)
            try:
                super(HelloHandler, self).dispatch()
            finally:
                self.session_store.save_sessions(self.response)
    
        @webapp2.cached_property
        def session(self):
            return self.session_store.get_session()
    
        def get(self):
            self.session['hello'] = 'world'
            self.response.headers['content-type'] = 'text/plain'
            self.response.write('Hello world')
    
    
    webapp2_config = { 
        'webapp2_extras.sessions': {
            'secret_key': 's3cr3t',
            'cookie_args':{'samesite': 'strict'}
        },  
    }
    
    application = webapp2.WSGIApplication([
        webapp2.Route(r'/', handler=HelloHandler),
    ],
        config=webapp2_config)
    

    The response's set-cookie header is

    session=eyJoZWxsbyI6IndvcmxkIn0=|1595151290|09b22484901689e6eb0411792c8732ef134d2b66; Path=/; SameSite=strict