I'm developing a react (16.9.0) single page app that uses axios (0.19.0). The axios requests use token authentication to access a server running django-rest-framework (3.6.4) and django-cors-headers (3.1.1). The authentication tokens are generated by django-rest-auth (0.9.5) during login.
The app works reliably in Chrome and Firefox. In Safari, some of requests fail due to 401 errors.
This requests succeeds in all three browsers:
INFO basehttp: "GET /apis/games/?slug=pop HTTP/1.1" 200 60932```
the code that generates it looks like:
axios
.get(`${simplUrl}/apis/games/?slug=${gameSlug}`, {
headers: { Authorization: simplToken },
})
.then(res => {
this.setState({
game: res.data[0],
});
...
This request failed with 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
but succeeded with 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
the code that generates it looks like:
const url = `${simplUrl}/apis/runs/${run.id}`;
// console.log('url:', url);
axios
.delete(url, {
headers: { Authorization: simplToken },
})
.then(res => {
// console.log(res);
afterDelete();
});
The Safari 401 response was:
"detail": "Authentication credentials were not provided."
This is the information Safari logged for the failed DELETE request:
The DRF apis views use are based on this mixing:
class CommonViewSet(viewsets.ModelViewSet):
authentication_classes = (TokenAuthentication, BasicAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
For local development, the DRF server's CORS settings are:
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
I don't understand why some requests fail in Safari while others do not. Mostly, I want to insure all requests work in all three browsers.
The solution was to add a trailing slash to urls referencing a single object. The DRF Router docs indicate the correct pattern is:
URL pattern: ^users/{pk}/$ Name: 'user-detail'
Whether it's a bug or a feature that Safari doesn't include the authentication token in redirected requests resulting a 401 error, I'll leave to the reader.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With