Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cookies not set or sent in request in iOS Safari or Chrome works on all Android and Desktop Browsers

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.

issues the cookie with tokens included

(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)

create a response to return to the device

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.

like image 632
Jonathan Wong Avatar asked Jan 24 '19 20:01

Jonathan Wong


1 Answers

Had the same problem and it was due to the path, setting it to '/' again was fine:

// caused problem:
let path = req.headers.host   //  setting this will allow it to be passed to subdomains

// ok:
// let path = '/'       
...
res.cookie( COOKIE_HTTPONLY_JWT, jwttoken, jwtopts ) 
like image 101
Tom Conlon Avatar answered Oct 20 '22 15:10

Tom Conlon