Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Axios requests using authentication token sometimes fail in Safari

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: enter image description here

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.

like image 381
softweave Avatar asked Feb 01 '20 19:02

softweave


1 Answers

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.

like image 120
softweave Avatar answered Nov 07 '22 04:11

softweave