Categories
Python

Securing REST APIs: Basic HTTP Authentication with Python / Flask

In our last tutorial on REST API Best Practices, we designed and implemented a very simple RESTful mailing list API. However our API (and the data) was open to public, anyone could read / add / delete subscribers from our mailing list. In serious projects, we definitely do not want that to happen. In this post, we will discuss how we can use http basic auth to authenticate our users and secure our APIs.

PS: If you are new to REST APIs, please check out REST APIs: Concepts and Applications to understand the fundamentals.

Setup API and Private Resource

Before we can move on to authentication, we first need to create some resources which we want to secure. For demonstration purposes, we will keep things simple. We will have a very simple endpoint like below:

If we launch the server and access the endpoint, we will get the expected output:

Our API is for now public. Anyone can access it. Let’s secure it so it’s no longer publicly accessible.

Basic HTTP Authentication

The idea of Basic HTTP Authentication is pretty simple. When we request a resource, the server sends back a header that looks something like this: WWW-Authenticate →Basic realm=”Authentication Required”. Generally when we try to access such resources from a browser, the browser shows us a prompt to enter username and password. The browser then base64 encodes the data and sends back an Authorization header. The server parses the data and verifies the user. If the user is legit, the resource is accessible, otherwise we are not granted permission to access it. 

While using a REST Client, we would very often need to pass the credentials before hand, while we make the request. For example, if we’re using curl, we need to pass the --user option while running the command.

Basic HTTP Authentication is a very old method but quite easy to setup. Flask HTTPAuth is a nice extension that would help us with that.

Install Dependencies

Before we can start writing codes, we need to have the necessary packages installed. We can install the package using pip:

Once the package is installed, we can use it to add authentication to our API endpoints.

Require Login

We will import the HTTPBasicAuth class and create a new instance named auth. It’s important to note that name because we will be using methods on this auth instance as decorators for various purposes.  For example, we will use the @auth.login_required decorator to make sure only logged in users can access the resource.

In our resource, we added the above mentioned decorator to our get method. So if anyone wants to GET that resource, s/he needs to login first. The code looks like this:

If we try to access the resource without logging in, we will get an error telling us we’re not authorized. Let’s send a quick request using curl.

So it worked. Our API endpoint is now no longer public. We need to login before we can access it. And from the API developer’s perspective, we need to let the users login before they can access our API. How do we do that?

Handling User Logins

We would generally store our users in a database. Well, a secured database. And of course, we would never store user password in plain text. But for this tutorial, we would store the user credentials in a dictionary. The password will be in plain text.

Flask HTTP Auth will handle the authentication process for us. We just need to tell it how to verify the user with his/her username and password. The @auth.verify_password decorator can be used to register a function that will receive the username and password. This function will verify if the credentials are correct and based on it’s return value, HTTP Auth extension will handle the user auth.

In the following code snippet, we register the verify function as the callback for verifying user credentials.  When the user passes the credentials, this function will be called. If the function returns True, the user will be accepted as authorized. If it returns False, the user will be rejected. We have kept our data in the USER_DATA dictionary.

Once we have added the above code, we can now test if the auth works.

But if we omit the auth credentials, does it work?

It doesn’t work without the login. Perfect! We now have a secured API endpoint that uses basic http auth. But in all seriousness, it’s not recommended.  That’s right, do not use it in the public internet. It’s perhaps okay to use inside a private network. Why? Please read this thread.

Wrapping Up

With the changes made, here’s the full code for this tutorial:

As discussed in the last section, it’s not recommended to use basic http authentication in open / public systems. However, it is good to know how http basic auth works and it’s simplicity makes beginners grasp the concept of authentication / API security quite easily.

You might be wondering – “If we don’t use http auth, then what do we use instead to secure our REST APIs?”. In our next tutorial on REST APIs, we would demonstrating how we can use JSON Web Tokens aka JWT to secure our APIs. Can’t wait for that long? Go ahead and read the introduction.

And don’t forget to subscribe to the mailing list so when I write the next post, you get a notification!

Categories
Golang

Golang / The Go Programming Language

The Go Programming language (often written as golang) has become quite popular recently. Google is actively backing the project  but Golang has seen usage, contribution and success stories from many other popular brands and enterprises across the internet. Go promises a very simple, easy to learn syntax that allows us to build robust, reliable, efficient software. Once we have had invested some time writing  production grade code in the language, we would agree that Go delivers on it’s promises. It’s indeed a fantastic language – easy to learn, easy to read, reason about and of course maintain. You get superb performance without sacrificing much on productivity. Don’t just trust my words, give it a Go! (See what I did there?)

A little history

Work on Golang started back in 2007 by Robert Griesemer, Rob Pike, and Ken Thompson at Google. So that kinds of make Golang 10 years old in 2017. Although work started in 2007, the language was however announced in 2009. It reached version 1.0 in 2012.

A little about the creators – Rob Pike was a member of the unix team and he is known for his work on Plan 9. Ken Thompson designed and implemented Unix. He also created the B language (from which C was inspired). He was also involved in the Plan 9 project.

Why did they start working on a new language? Because they were frustrated with the ones that existed. You can choose a dynamic language like Python / Javascript and enjoy the ease of programming in them. Or you can choose something like C/C++ to get performance. But at the same time you lose the ease of programming, productivity reduces and the compilation time can sometimes get too long. More and more developers were choosing dynamic languages in their projects, essentially favouring the ease of use over the safety and performance offered by the statically typed, compiled languages. There wasn’t any popular, easy to use, mainstream language that could ease these problems for the developers. You couldn’t get ease of programming, safety, efficiency, fast compilation – all from a single language.

The creators of Golang saw this problem as an opportunity to create a better language that could solve these problems at hand.

Why did Golang become so popular?

Go came with better offerings, specially with solutions to what many of us (including the Googlers) faced. When I read (or write) Go code, I feel like the following equation makes perfect sense => C + Python = Golang. Go is very very fast. Not just the language but also the compiler. Go compiles fast, runs fast. And you still feel quite productive, much more productive than you would feel in C++ or Java.

The syntax is simple. You won’t have to remember many keywords.  The static typing provides safety to a great extent. IDEs can provide better code completion and refactoring assistance. Compiler would help you reduce bugs by catching many potential errors before the program even starts to run (which is applicable to all statically typed languages, nothing Golang specific but with Go’s “light on keywords” design, it’s just more productive and enjoyable).

Go provides a nice, extensive standard library with all the batteries you might need for day to day system or network programming. You want to build an awesome web app? Go standard library has you (mostly) covered.

The major win for Go is perhaps the concurrency primitives. We can create very light weight threads called goroutine which are multiplexed on all available CPU cores. We can easily communicate between the goroutines using channels. I personally found the goroutine and channels based way of writing efficient concurrent programs very easy, elegant and pleasant. Don’t be afraid of writing highly concurrent programs any more!

Golang also compiles everything and generates a single binary that includes everything that you need to run the program. You do not need to have anything installed on your target machine to run the binary. This is a huge win in terms of deployment. Writing and distributing command line tools have never been easier!

How popular is Golang?

It’s quite popular. Golang is currently ranked 16 on the TIOBE Index. Tiobe also declared Go to be the language of the year in 2016. Interestingly they also chose Go as the language of the year back in 2009, the year it was released. It stands 15th on the RedMonk language ratings. If you compare active repositories using Githut, Go would be the 14th most active language on Github. For a new programming language, that has released it’s first major version in 2012, that ranking is quite impressive. If you think about the growth of the language, it’s been getting a lot of traction.

In the latest StackOverflow Survey (2017), Go is 3rd on the most wanted list and 5th on the most loved list. That tells us something, doesn’t it? 😀

gopher with a gun
Gopher with a Gun!

How’s the job market, you ask? Don’t worry, Go has jobs for you!

Also check out the HackerNews “Who is hiring?” threads. I see a lot of Golang related job postings there. And do not forget, Golang pays well.

I want to learn Golang

I am sure you do.  So where can we learn Golang by ourselves? These are my recommendations:

  • The Official Tour is excellent. I recommend it to all the beginners. You will have a very good basic once you complete the tour. The tour is also available offline in case you want to learn some golang while on vacation or on the go.
  • Go By Example is another excellent step by step tour. I always refer to this site when I need to lookup a syntax or need a quick reference.
  • Effective Go is a nice read if you want to learn the best practices and want to write idiomatic Go codes.
  • The Little Go Book is a great free book for learning Go.
  • Official Documentation is something we all should keep close to us while writing some Go code.
  • The Go Blog – This is something I really really love. The official Go blog has many interesting and detailed stuff. Trust me, there’s a lot to learn from there. Highly recommended.

If you need some help, please feel free to ask in Gophers Slack or the Go Forum maintained by the GoBridge people.

Categories
Python

REST API Best Practices: Python & Flask Tutorial

In our last post about REST APIs, we have learned the basics of how REST APIs function. In this post, we would see how we can develop our own REST APIs. We would use Python and Flask for that. If you are new to Python, we have you covered with our Python: Learning Resources and Guidelines post.

Python / Flask code is pretty simple and easy to read / understand. So if you just want to grasp the best practices of REST API design but lack Python skills, don’t worry, you will understand most of it. However, I would recommend you try out the codes hands on. Writing codes by hand is a very effective learning method. We learn more by doing than we learn by reading or watching.

Installing Flask and Flask-RESTful

We will be using the Flask framework along with Flask-RESTful. Flask-RESTful is an excellent package that makes building REST APIs with Flask both easy and pleasant. Before we can start building our app, we first need to install these packages.

Once we have the necessary packages installed, we can start thinking about our API design.

RESTful Mailing List

You see, I just recently started this Polyglot.Ninja() website and I am getting some readers to my site. Some of my readers have shown very keen interest to receive regular updates from this blog. To keep them posted, I have been thinking about building a mailing list where people can subscribe with their email address. These addresses get stored in a database and then when I have new posts to share, I email them. Can we build this mailing list “service” as a REST API?

The way I imagine it – we will have a “subscribers” collection with many subscriber. Each subscriber will provide us with their full name and email address. We should be able to add new subscriber, update them, delete them, list them and get individual data. Sounds simple? Let’s do this!

Choosing a sensible URL

We have decided to build our awesome mailing list REST API. For development and testing purposes, we will run the app on my local machine. So the base URL would be http://localhost:5000. This part will change when we deploy the API on a production server. So we probably don’t need to worry about it.

However, for API, the url path should make sense. It should clearly state it’s intent. A good choice would be something like /api/ as the root url of the API. And then we can add the resources, so for subscribers, it can be /api/subscribers. Please note that it’s both acceptable to have the resource part singular (ie. /api/subscriber) or plural (/api/subscribers). However, most of the people I have talked to and the articles I have read, more people like the plural form.

API Versioning: Header vs URL

We need to think about the future of the API before hand. This is our first iteration. In the future, we might want to introduce newer changes. Some of those changes can be breaking changes. If people are still using some of the older features which you can’t break while pushing new changes, it’s time you thought about versioning your API. It is always best practice to version your API from the beginning.

The first version of the api can be called v1. Now there are two common method of versioning APIs – 1) Passing a header that specifies the desired version of the API  2) Put the version info directly in the URL. There are arguments and counter arguments for both approaches. However, versioning using url is easier and more often seen in common public APIs.

So we accommodate the version info in our url and we make it – /api/v1/subscribers. Like discussed in our previous REST article, we will have two types of resources here – “subscriber collection” (ie. /subscribers) and “individual subscriber” elements (ie. /subscribers/17).  With the design decided upon and a bigger picture in our head, let’s get to writing some codes.

RESTful Hello World

Before we start writing our actual logic, let’s first get a hello world app running. This will make sure that we have got everything setup properly. If we head over to the Flask-RESTful Quickstart page, we can easily obtain a hello world code sample from there.

Let’s save this code in a file named main.py and run it like this:

If the code runs successfully, our app will launch a web server here – http://127.0.0.1:5000/. Let’s break down the code a bit:

  • We import the necessary modules (Flask and Flask-RESTful stuff).
  • Then we create a new Flask app and then wrap it in Api.
  • Afterwards, we declare our HelloWorld resource which extends Resource.
  • On our resource, we define what the get http verb will do.
  • Add the resource to our API.
  • Finally run the app.

What happens here, when we write our Resources, Flask-RESTful generates the routes and the view handlers necessary to represent the resource over RESTful HTTP. Now let’s see, if we visit the url, do we get the message we set?

If we visit the url, we would see the expected response:

Trying out REST APIs

While we develop our api, it is essential that we can try out / test the API to make sure it’s working as expected. We need a way to call our api and inspect the output. If you’re a command line ninja, you would probably love to use curl. Try this on your terminal:

This would send a GET request to the URL and curl would print out the response on the terminal. It is a very versatile tool and can do a lot of amazing things. If you would like to use curl on a regular basis, you may want to dive deeper into the options / features / use cases. These can help you:

However, if you like command line but want a friendlier and easier command line tool, definitely look at httpie.

httpie vs curl
httpie vs curl command

 

Now what if you’re not a CLI person? And we can agree that sometimes GUI can be much more productive to use. Don’t worry, Postman is a great app!

If you are developing and testing a REST API, Postman is a must have app!

postman interface
Our newly created API in Postman

Back to Business

We now have a basic skeleton ready and we know how to test our API. Let’s start writing our mailing list logic. Let’s first layout our resources with some sample data. For this example, we shall not bother about persisting the data to some database. We will store the data in memory. Let’s use a list as our subscriber data source for now.

What changes are notable here?

  • Note we added a prefix to the Api for versioning reason. All our urls will be prefixed by /api/v1.
  • We created a list named users to store the subscribers.
  • We created two resources – SubscriberCollection and Subscriber.
  • Defined the relevant http method handlers. For now the response just describes the intended purpose of that method.
  • We add both resources to our api. Note how we added the id parameter to the url. This id is available to all the methods defined on Subscriber.

Fire up the local development server and try out the API. Works fine? Let’s move on!

Parsing Request Data

We have to accept, validate and process user data. In our cases, they would be the subscriber information. Each subscriber would have an email address, a full name and ID. If we used a database, this ID would have been auto generated. Since we are not using a database, we would accept this as part of the incoming request.

For processing request data, the RequestParser can be very helpful. We will use it in our POST calls to /api/subscribers/ to validate incoming data and store the subscriber if the data is valid. Here’s the updated code so far:

Here we have made two key changes:

  • We created a new instance of RequestParser and added arguments so it knows which fields to accept and how to validate those.
  • We added the request parsing code in the post method. If the request is valid, it will return the validated data. If the data is not valid, we don’t have to worry about it, the error message will be sent to the user.

Testing the request parser

If we try to pass invalid data, we will get error messages. For example, if we request without any data, we will get something like this:

But if we pass valid data, everything works fine. Here’s an example of valid data:

This will get us the following response:

Cool, now we know how to validate user data 🙂 Please remember – never trust user input. Always validate and sanitize user data to avoid security risks.

Next, we need to implement the user level updates.

Subscriber Views

We went ahead and completed the code for the rest of the methods. The updated code now looks like this:

What did we do?

  • We added a helper function to find users from the list by it’s id
  • The update view works – we can update the user data. In our case we’re deleting the data and adding the new data. In real life, we would use UPDATE on the database.
  • Delete method works fine!

Feel free to go ahead and test the endpoints!

HTTP Status Codes

Our mailing list is functional now. It works! We have made good progress so far. But there’s something very important that we haven’t done yet. Our API doesn’t use proper http status codes. When we send response back to the client, we should also give it a status code. This code would help the client better interpret the results.

Have you ever visited a website and saw “404 Not found” error? Well, 404 is the status code, that means the document / resource you were looking for is not available. Saw any “500 Internal Server Error” lately? Now you know what that 500 means.

We can see the complete list of http status codes here: https://httpstatuses.com/.

Also depending on whether you’re a cat person or a dog enthusiast, these websites can explain things better:

So let’s fix our code and start sending appropriate codes. We can return an optional status code from our views. So when we add a new subscriber, we can send  201 Created like this:

And when we delete the user, we can send 204.

What’s next?

We have made decent progress today. We have designed and implemented a very basic API. We chose a sensible url, considered API versioning, did input validation and sent appropriate http status codes. We have done good. But what we have seen here is a very simple implementation. There are a lot of scope of improvements here. For example, our API is still open to public, there is no authentication enabled. So anyone with malicious intentions can flood / spam our mailing list database. We need to secure the API in that regard. We also don’t have a home page that uses HATEOAS to guide the clients. We don’t yet have documentation – always remember, the documentation is very important. We developers often don’t feel like writing documentation but well written documentation helps the consumers of your API consume it better and with ease. So do provide excellent docs!

I don’t know when – but in our next post on REST APIs, we shall explore more into the wonderful world of API development. And may be we shall also talk about some micro services? If you would like to know when I post those contents, do subscribe to the mailing list. You can find a subscription form on the sidebar.

And if you liked the post, do share with your friends 🙂