My project this weekend was to optimize my site for security, and performance to prepare for an upcoming launch. Although I hadn’t been ignoring these things completely, I figured it was a good chance to step back and check where I was at and tweak where necessary. In this post I’m going to go over the steps I took to implement security measures in my Django site.
Note: before you check, none of the things I’m discussing here have been done on this site you’re reading. Right now I’m working exclusively on my Django side project, although I definitely would like to implement similar steps to my personal site soon.
My focus on security for this weekend was specifically on HTTP security. I’ve never really implemented HTTP security before, so for me this was totally a learning experience. I started off by adding an SSL cert to my Heroku server. They make it terribly easy to do since a cert comes free with any paid server. So after upgrading my Heroku server to the paid Hobby dyno I was feeling pretty good about myself. Security issues solved, right?
Okay, maybe not. A quick scan using Observatory by Mozilla made all my dreams of becoming a security super hero come crashing to a halt. My site had a big, fat F. (That’s for Fail, not Fantastic.) So what did I need to work on?
Perhaps a better title for this blog series would be “Django lessons learned the hard way”, since I seem to only have something to write about when I’ve really screwed something up and had to struggle to fix it. Usually that error came from not thinking out my data structures from the beginning, and having to back track.
Here’s where I screwed up this time. In my project I have a model called “Organization” which holds information about companies in my app. I’d built the model several months ago and went on my merry way creating objects and adding some related data when I realized, I had forgotten to add a user group to hold the administrators of the companies. This group is incredibly important because it will define who is allowed to view certain information about the company and edit details about it. Realizing my mistake I went back to add the group foreign key field, which would be fairly straight forward if it were a nullable field. Since it isn’t though, it takes a few steps to add it to the model.
In this mini tutorial we’ll add a new non-nullable One To One Field representing the administrator group for an organization. As always, I want to add the caveat here that I am still just a learner myself, so I may not know the best solution, but it’s one that has worked for me!
I’ve recently started learning to program in Python with a Django front-end, and I’ve found that while most problems I come across can very easily be solved by looking at Django’s documentation, or by finding an answer on StackOverflow, occasionally I’ll come across a problem that I have to Google around for hours to figure out, piecing together solutions from all sorts of different sources. So I thought, I’ll post the solutions I finally figure out, and maybe, sometime down the road, some other Django newbie will find my article and it might save them a couple of hours.
With that, I give you my very first Django mini-tutorial!
Today’s problem was about redirecting. Whenever a view in Django uses the very handy @login_required decorator, you may notice that the URL for the login page contains a URL parameter indicating where the user should be redirected after they log in. For example, the URL might be www.domain.com/login/?next=/profile/5/, indicating that when the user completes logging in they should be redirected to user 5’s profile page. That’s all well and good… as long as the user already has an account. But if you wanted to have a sign up link at the bottom of your sign in form to allow the user to register, then the context will be lost. So my goal was to pass the “next” parameter on to the create account link so that the user will still be redirected to user 5’s profile after creating their shiny new account.