未在 iOS Safari 或 Chrome 请求中设置或发送的 Cookie 适用于所有 Android 和桌面浏览器

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

我使用在后端制作的 set-cookie header 在设备上设置安全的 http-only cookie。这在桌面 Safari、Chrome、FF、IE 等上非常有效。这也适用于 Android Chrome。但是,当我尝试在移动 Safari 或 Chrome 上 iOS 上从我的网络应用程序 运行 完全相同的代码时,请求中没有发送任何 cookie,并且我的网络应用程序无法运行。

我尝试查看其他堆栈溢出答案和问题,并且尝试修改我的设置并测试几个不同的 iOS 设备。我希望我的网络应用程序在不修改默认 iOS Safari 设置的情况下运行。我真的不明白为什么 iOS 不起作用..因为这种行为似乎是前所未有的。

发出包含令牌的 cookie

(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

(我 return 回复)

创建对 return 到设备的响应

response = {"statusCode": 200,
"headers": customfuncs.makeHeader(authorization.issueCookieTokens(userItem)),
"body": json.dumps({'Item': userItem}, cls=decimalencoder.DecimalEncoder)}
return response

我希望我对 return 的回复成功,将我的 json 包含在 return body 中,并成功 return 一个 header 使用 set-cookie header 设置一个 cookie 来存储一个安全的 http-only cookie,该 cookie 为用户存储我的 access/refresh 令牌。 cookie 也应该在后续请求中发送。如果您想自己测试,该站点是 https://swipeme.in 。我在登录和注册期间存储 cookie。测试 cookie 集和被发送回来的最佳方法是在注册和下一个请求中 photo-upload.

有同样的问题,是路径的问题,再次设置为'/'就可以了:

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

有两件事很重要,可以使这个 cookie(安全,httpOnly)设置过程正常工作。

  1. 确保客户端上的请求始终包含与“Allow-Credentials”匹配的凭据https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials

  2. 如果您使用的是安全的、仅限 http 的 cookie,则您请求的 API 需要来自同一域。 (例如,如果我的网站托管在 https://swipeme.in, the api it request must be something like https://api.swipeme.in

我 运行 在使用不同域的 AWS Lambda 函数时遇到了这个问题。然后我将 API 网关配置为使用我的自定义域来修复它。