API Design: HTTP Basic Authentication vs API Token
I'm currently creating an authentication system on front of a public web API for a web application. Given that each user account has an API key and each request must be authenticated, I have two alternatives:
-
Using an HTTP Basic Authentication, like GitHub does.
Requests must be sent to the URL
http://api.example.com/resource/id with basic authentication username: token password: the api key
-
Passing the API Token as querystring parameter.
Requests must be sent to the URL
http://api.example.com/resource/id?token=api_key
There's also a third option which is passing the token within the URI, but I honestly don't like that solution.
Which solution would you adopt and why?
Solution 1:
Best bet might be using an API key in the header (e.g. 'Authorization: Token MY_API_KEY') instead of as a url param:
Advantages over HTTP Basic Auth:
- More convenient, as you can easily expire or regenerate tokens without affecting the user's account password.
- If compromised, vulnerability limited to API, not the user's master account
- You can have multiple keys per account (e.g. users can have "test" and "production" keys side by side.)
Advantages over API key in URL:
- Provides extra measure of security by preventing users from inadvertently sharing URLs with their credentials embedded in them. (Also, URL can wind up in things like server logs)
Solution 2:
Many times I had to think about how to authenticate users/requests onto APIs and after comparing more solutions I ended up with using the Amazon's solution where I don't need or I can't use OAuth. This solution is based on signatures that prevents from "man in the middle" problems as Basic Auth and passing a simple token are sending plain text data. Yes you can add ssl but this will add complexity to the system...
Solution 3:
I think that HTTP Basic Auth should be OK but just for really simple needs.
The complete (and final) solution IMHO is to implement an OAuth provider. It's not complex, it's a simple protocol and gives you lots of flexibility. In addition it seems to be the current trend as many big players implement it and it's supported from many many libraries.