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.
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×tamp=%s&hash=%s” % (settings.ZENDESK_URL, first, last, u.email, timestamp, hash)
return HttpResponseRedirect(url)
Cheers,
Alexander
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!
Great work Alexander, I’ll have to merge in those changes. I may bundle this up as an app, I was debating it because it’s so simple but it’s separate functionality which is normally a good enough reason.
You’re right, it’s just one view so it’s not an obvious app candidate. But it’s definitely code that begs for reuse.
Here she is, django_zendesk.
Thanks for this post. I am new at development and this is a big help.