I use a set-cookie header made on the backend to set a secure, http-only cookie on the device. This has worked like a charm on desktop Safari, Chrome, FF, IE etc. This also works on Android Chrome. However, when I tried to run the same exact code from my web app on iOS in mobile Safari or Chrome, no cookie is sent in the request and my web app does not work.
I've tried looking at other stack overflow answers and questions and I've tried modifying my settings and testing whether several different iOS devices. I want my web app to work without modifying the default iOS Safari settings. I genuinely don't understand why iOS isn't working.. as this behavior seems unprecedented.
(authorization.py)
#creates the cookie string for the response
def setCookie(name, value, expires='', domain=None,
secure=False, httponly=False, path=None):
morsel = cookies.Morsel()
# morsel.set(name, value, quote(value))
morsel.set(name, value, value)
expires = datetime.utcnow() + timedelta(days=365)
expireStr = expires.strftime("%a, %d %b %Y %X GMT")
print(expireStr)
morsel['expires'] = expireStr
if path:
morsel['path'] = path
if domain:
morsel['domain'] = domain
if secure:
morsel['secure'] = secure
value = morsel.OutputString()
if httponly:
value += '; httponly'
print(value)
return value
def issueCookieTokens(userData):
accessToken = issueAccessToken(userData).decode('utf-8')
refreshToken = issueRefreshToken(userData).decode('utf-8')
tokens = {'accessToken': accessToken, 'refreshToken': refreshToken}
return setCookie('tokens', json.dumps(tokens), path= '/', secure=True, httponly=True)
(customfuncs.py)
headers = {
'Access-Control-Allow-Origin': 'REDACtED',
'Access-Control-Allow-Credentials': True
}
def makeHeader(cookieVal):
newHeader = headers
print("cookieVal: " + cookieVal)
newHeader['Set-Cookie'] = cookieVal
print(newHeader['Set-Cookie'])
return newHeader
(where I return the response)
response = {"statusCode": 200,
"headers": customfuncs.makeHeader(authorization.issueCookieTokens(userItem)),
"body": json.dumps({'Item': userItem}, cls=decimalencoder.DecimalEncoder)}
return response
I expect my response to return successfully, encompassing my json in the return body, and successfully returning a header that sets a cookie using the set-cookie header to store a secure, http-only cookie that stores my access/refresh tokens for the user. The cookie should also be sent up in subsequent requests. If you would like to test it for yourselves, the site is https://swipeme.in . I store cookies during login and signup. The best way to test the cookies set and being sent back up would be in the signup and in the next request which would be photo-upload.
There are two things that are important to do that will make this cookie(secure, httpOnly) setting process work.
Make sure that requests on the client always include credentials to match "Allow-Credentials" https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials
If you are using secure, http only cookies, the API that you request needs to be from the same domain. (For example if my site was hosted on https://swipeme.in, the api it request must be something like https://api.swipeme.in)
I ran into this issue when I was using AWS Lambda functions with a different domain. I then configured API Gateway to use my custom domain to get it fixed.