Zendesk remote authentication with Django

I had a pleasant time yesterday hooking Zendesk into an existing Django site (using django.contrib.auth). Their API has a hook for remote authentication which is a lot easier than their chart makes it look. Actually it was accomplished in only a couple lines of Python.

You need to tell Zendesk two URLs, one for where it sends users to log-in and then another for where to send them when they log-out. For me that meant creating one new view (to send the login details to Zendesk). Here’s about what it looks like:

@login_required
def authorize(request):
    
    try:
        timestamp = request.GET['timestamp']
    except KeyError:
        raise Http404
    
    u = request.user
    
    hash = md5.new('%s %+s%s%s%s' % (u.first_name, u.last_name, u.email, settings.ZENDESK_TOKEN, timestamp)).hexdigest()
    
    url = "%s/access/remote/?name=%s %s&email=%s×tamp=%s&hash=%s" % (settings.ZENDESK_URL, u.first_name, u.last_name, u.email, timestamp, hash)
    
    return HttpResponseRedirect(url)

That’s it. We’re hooked in. It requires two custom settings (ZENDESK_TOKEN and ZENDESK_URL) which you get from Zendesk, but otherwise should work in your Django app. When the user clicks “login” from Zendesk, they get directed to this view with a GET variable called timestamp. The view makes sure the user is authenticated (if not it shows the login page and gets the user to login) and then creates a hash to send over to Zendesk. To the user it’s all transparent. Kudos to Zendesk on making it so easy.

Update: I have made this into its own pluggable Django app called django_zendesk and posted it up on BitBucket.

Read the latest posts

6 Responses to “Zendesk remote authentication with Django”

  1. Hey Jon,

    Great tip. Since the md5 module is deprecated since Python 2.5, I rewrote the code ever so slightly to use the new “hashlib” instead. Also, Zendesk requires names for their users so if that’s not always available logins may fail. Easily fixed by making up a dummy name when needed. Here’re both changes:

    @login_required
    def authorize(request):
    try:
    timestamp = request.GET[‘timestamp’]
    except KeyError:
    raise Http404

    u = request.user

    first = u.first_name
    last = u.last_name
    if not first and not last:
    first = “Anon”
    last = “Ymous”

    from hashlib import md5
    hash = md5(‘%s %+s%s%s%s’ % (first, last, u.email, settings.ZENDESK_TOKEN, timestamp)).hexdigest()

    url = “%s/access/remote/?name=%s %s&email=%s&timestamp=%s&hash=%s” % (settings.ZENDESK_URL, first, last, u.email, timestamp, hash)

    return HttpResponseRedirect(url)

    Cheers,
    Alexander

  2. We made another update to the code snippet to support unicode names. Posted a longer explanation and formatted source code on our blog. Hope it helps!

  3. Dana Ard says:

    Thanks for this post. I am new at development and this is a big help.

Leave a Reply to Alexander Ljungberg