I'm implementing for first time a login Auth with HTTpOnly Cookie. In my case, the cookie it's created when user calls login method in a Python service with fastapi and uvicorn.
I've read the MDN documentation to implement the expires property and so, the browser delete this cookie when the time expires.
I've implemented the Cookie in Python with http.cookies and Morsel to apply the HttpOnly property like this:
from http import cookies
from fastapi import FastAPI, Response, Cookie, Request
from fastapi.responses import HTMLResponse, FileResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
mytoken = 'blablabla'
def getUtcDate():
sessionDate = datetime.now()
sessionDate += timedelta(minutes=2)
return sessionDate.strftime('%a, %d %b %Y %H:%M:%S GMT')
@app.get('cookietest')
def getCookie(response: Response):
cookie = cookies.Morsel()
cookie['httponly'] = True
cookie['version'] = '1.0.0'
cookie['domain'] = '127.0.0.1'
cookie['path'] = '/'
cookie['expires'] = getUtcDate()
cookie['max-age'] = 120
cookie['samesite'] = 'Strict'
cookie.set("jwt", "jwt", mytoken)
response.headers.append("Set-Cookie", cookie.output())
return {'status':'ok'}
Doing this, the Cookies looks correctly in the browser when I call the 'cookietest' endpoint, the evidence:
As you can see in the picture, the cookie has an expiration datetime in Expires / Max-Age:"Wed, 12 Oct 2022 11:24:58 GMT", 2 minutes after logging in (if the user logging at 14:05:00, the cookies expires at 14:07:00)
My problem is that any browser doesn't delete the cookie when the expire time has been exceeded, so this it's confusing me. If I let several minutes pass and then make a request to another endpoint (like http://127.0.0.1:8000/info), the cookie still exists in http headers.
What is the problem? What i'm doing wrong? I'm reading a lot of documentation about cookie storing and expiration and I can't see anything about this issue.
Many thanks Regards
EDITED : PROBLEM SOLVED
As Chris says, using the set_cookie method from FastApi the problem was solved.
I still wonder why the MSD documentation indicates that the date format must be a specific one which does not cause the browser to delete the Cookie, but indicating the time in seconds works correctly.
@app.get("/cookietest")
async def cookietest(response: Response):
response.set_cookie(
key='jwt',
value=getToken(),
max_age=120,
expires=120,
path='/',
secure=False,
httponly=True,
samesite="strict",
domain='127.0.0.1'
)
return {"Result": "Ok"}
set_cookie
method of theResponse
object, as described in this answer. See the relevant FastAPI documentation and Starlette documentation as well. – Dupreeexpires
flag in theset_cookie
method, which takes an integer that defines the number of seconds until the cookie expires. For instance, if you want the cookie to expire in 2 minutes from the time it is created, useexpires=120
. – Dupree