Skip to content

Instantly share code, notes, and snippets.

@markyv18
Last active June 8, 2017 08:45
Show Gist options
  • Save markyv18/07451a56624f52e7c8a1c8df295c1ac3 to your computer and use it in GitHub Desktop.
Save markyv18/07451a56624f52e7c8a1c8df295c1ac3 to your computer and use it in GitHub Desktop.
Locking down API endpoints
We just completed a two week sprint where we focused on additional feature build out of www.thumbtack.com, refining the user experience, and creation of various API endpoints that contained sales/marketing data. One particular element that I tasked myself with was the creation of previously mentioned API data as well as the locking down of access to our various APIs. Yak shaving was ever present in this endeavour.
After a few flase starts I came upon the Blazer gem that I was very quickly able to get up and running. Three to four lines of code in three different files, a migration and -*viola*- a browser-GUI SQL sandbox to play around in. Tinkering around with this I was able to slowly build out my queries by continually appending more filtration. At first it was plug and play guessing but by the third data set things were moving much faster. Will be using blazer again in the future. As a side note, there is a terminal command for accessing a postgresql console, much like the rails console, attempts to find this went unrewarded.
Upon completion of the endpoints I set out to make a key to lock access to them. Again, more yak shaving as the first few tutorials failed to get me anywhere. Then, I hit pay dirt. http://railscasts.com/episodes/352-securing-an-api?view=asciicast
Basically it goes as such:
in the terminal run
rails g model api_key access_token
then migrate
in the api_key model include underneath the class line:
before_create :generate_access_token
and define this in a private method at the bottom of the class with
begin
self.access_token = SecureRandom.hex
end while self.class.exists?(access_token: access_token)
Great! Now you can create a Key. You'll need to build out the routes and show/index and create methods as well as the erb view in order to present the key to your end user.
Head on over to the controller where you are calling your API, underneath the class insert a
"before_filter :restrict_access <p> respond_to :json"
in a private method at the botom of this controller you define the :restric_access method with
api_key = ApiKey.find_by_access_token(params[:access_token])
head :unauthorized unless api_key
Boom, done! There are a few further security features you could add to the controller but I was not able to get them implemented in a timely fashion. Only wish I'd found railscast first!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment