Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I mix sessions auth and token auth in one site?

I have django application using sessions auth. I need to add API part. This API will be used by my app.users only (web browsers and mobiles devices as well). I would prefer to use token auth for API as it seems more robust. I found rest_framework_jwt that can handle it. My question: Can I mix sessions auth for web and token auth for API in one site without problems? I think about the web app and the API app as two different applications. So I want to separate them in my project, use different subdomain and use different kind of auth for each. Is it possible to separate auth by subdomain? I would like to send token when user log in to web app. Is it good idea?

like image 394
Joe Bobson Avatar asked Dec 22 '25 04:12

Joe Bobson


1 Answers

As you see in the documentation, you can configure multiple authentication backends without any problems. DRF will just try each one of the backends until one says "ok".

One thing to keep in mind: If you (for example) provide an invalid JSON-Web-Token then the authentication will immediately fail and other backends will not be tried. Good to see in the source of rest_framework_jwt.

def authenticate(self, request):
    """
    Returns a two-tuple of `User` and token if a valid signature has been
    supplied using JWT-based authentication.  Otherwise returns `None`.
    """
    auth = get_authorization_header(request).split()

    if not auth or auth[0].lower() != b'jwt':
        return None

    if len(auth) == 1:
        msg = 'Invalid JWT header. No credentials provided.'
        raise exceptions.AuthenticationFailed(msg)
    elif len(auth) > 2:
        msg = ('Invalid JWT header. Credentials string '
               'should not contain spaces.')
        raise exceptions.AuthenticationFailed(msg)

    try:
        payload = jwt_decode_handler(auth[1])
    except jwt.ExpiredSignature:
        msg = 'Signature has expired.'
        raise exceptions.AuthenticationFailed(msg)
    except jwt.DecodeError:
        msg = 'Error decoding signature.'
        raise exceptions.AuthenticationFailed(msg)

    user = self.authenticate_credentials(payload)

    return (user, auth[1])
  • return None means the backend saying: "this is not JWT, let the others try
  • raise exceptions.AuthenticationFailed(msg) means: "the user tried JWT, but the he failed it."

To answer the further questions:

  • no need for doing this in separate applications (but it's no problem if you want).
  • as you can read in "setting the authentication scheme" you can define global defaults for authentication backends, but you can also override them per View or ViewSet.
like image 194
Denis Cornehl Avatar answered Dec 24 '25 01:12

Denis Cornehl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!