使用身份验证令牌的 Axios 请求有时会在 Safari 中失败
Posted
技术标签:
【中文标题】使用身份验证令牌的 Axios 请求有时会在 Safari 中失败【英文标题】:Axios requests using authentication token sometimes fail in Safari 【发布时间】:2020-05-18 02:22:09 【问题描述】:我正在开发一个使用 axios (0.19.0) 的 react (16.9.0) 单页应用程序。 axios 请求使用令牌身份验证来访问运行 django-rest-framework (3.6.4) 和 django-cors-headers (3.1.1) 的服务器。身份验证令牌由 django-rest-auth (0.9.5) 在登录期间生成。
该应用可在 Chrome 和 Firefox 中可靠运行。在 Safari 中,部分请求会因 401 错误而失败。
此请求在所有三个浏览器中均成功:
INFO basehttp: "GET /apis/games/?slug=pop HTTP/1.1" 200 60932```
生成它的代码如下:
axios
.get(`$simplUrl/apis/games/?slug=$gameSlug`,
headers: Authorization: simplToken ,
)
.then(res =>
this.setState(
game: res.data[0],
);
...
此请求在 Safari 中失败:
INFO basehttp: "OPTIONS /apis/runs/43 HTTP/1.1" 200 0
INFO basehttp: "DELETE /apis/runs/43 HTTP/1.1" 301 0
INFO basehttp: "OPTIONS /apis/runs/43/ HTTP/1.1" 200 0
WARNING basehttp: "DELETE /apis/runs/43/ HTTP/1.1" 401 58
但使用 Chrome 成功:
INFO basehttp: "OPTIONS /apis/runs/43 HTTP/1.1" 200 0
INFO basehttp: "DELETE /apis/runs/43 HTTP/1.1" 301 0
INFO basehttp: "OPTIONS /apis/runs/43/ HTTP/1.1" 200 0
INFO basehttp: "DELETE /apis/runs/43/ HTTP/1.1" 204 0
生成它的代码如下:
const url = `$simplUrl/apis/runs/$run.id`;
// console.log('url:', url);
axios
.delete(url,
headers: Authorization: simplToken ,
)
.then(res =>
// console.log(res);
afterDelete();
);
Safari 401 响应是:
"detail": "Authentication credentials were not provided."
这是 Safari 为失败的 DELETE 请求记录的信息:
使用的 DRF api 视图基于这种混合:
class CommonViewSet(viewsets.ModelViewSet):
authentication_classes = (TokenAuthentication, BasicAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
对于本地开发,DRF 服务器的 CORS 设置为:
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
我不明白为什么有些请求在 Safari 中失败,而有些则没有。大多数情况下,我想确保所有请求在所有三种浏览器中都能正常工作。
【问题讨论】:
请展示您的“simplToken”变量的示例以及如何设置它。 在 DELETE 请求 url /apis/runs/43/ 中添加斜杠(末尾有斜杠)。我认为问题在于,当您调用 /apis/runs/43 (WITHOUT SLASH) 时,safari 会正确地重定向您(使用斜杠)但在 Authorization 标头中没有身份验证令牌(标头未转发)。 chrome也做同样的事情,但它重定向授权头。 您的建议解决了问题。谢谢@mon io。 【参考方案1】:解决方案是在引用单个对象的 url 中添加一个斜杠。 DRF Router docs 表示正确的模式是:
URL pattern: ^users/pk/$ Name: 'user-detail'
Safari 没有在重定向请求中包含身份验证令牌导致 401 错误是错误还是功能,我将留给读者。
【讨论】:
这也是我的问题。谢谢!【参考方案2】:你看到this了吗?我不太确定,但这个讨论可能会有所帮助。
此外,由于错误与token
有关,请尝试验证其是否正确发送或添加到请求中,或者它是否具有像承载或类似的类型。
还可以尝试记录传入的请求标头及其正文,以便确保没有任何内容丢失或损坏。
由于DELETE
出现此问题,请尝试将所有请求相互比较以找出缺少的内容。
【讨论】:
感谢您的回复。我为删除添加了 Safari 的网络日志记录。将考虑添加服务器端日志记录/调试。 因此,您首先发出请求,然后被重定向,然后在没有令牌的情况下再次尝试发出请求,然后获得未经授权的响应。好吧,对于第 3 次和第 4 次请求,没有任何问题,没有带有删除请求的令牌,因此您获得了未经授权,但是为什么您在第一个请求之后被重定向,以及为什么在没有令牌的情况下再次发送请求。 尝试使用没有扩展或默认设置或其他东西的 safari,也许有什么东西让它表现得像这样 我看到但不理解 Safari 的网络日志。在删除请求 url 中添加斜线解决了这个问题——以及其他页面上的许多类似 url 问题(例如“GET /apis/runs/44/”) 这很奇怪,实际上这是我第一次看到这个,这促使我搜索更多关于实际上我没有找到太多结果的信息,但这可能会添加更多信息***.com/questions/11348479/safari-adds-trailing-slash以上是关于使用身份验证令牌的 Axios 请求有时会在 Safari 中失败的主要内容,如果未能解决你的问题,请参考以下文章