63

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:

  1. 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
    
  2. 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?

5
  • What about a cookie with the token? Is that an alternative? Commented Feb 11, 2011 at 10:50
  • 11
    Not really. API Clients usually are scripts and they tend to not support cookies or sessions. Commented Feb 11, 2011 at 10:54
  • The github link is broken. Commented Apr 16, 2013 at 15:38
  • 3
    The link in the OP ("like GitHub does") is not HTTP Basic Authentication. HTTP-BA specifies the auth info to be carried in Authentication: headers. It's also not at all secure: the header value is a simple, easily reversible encoding of user name and password. It's no more secure than sending name and password in the clear (the encoding merely protects HTTP from funky characters). Commented Feb 19, 2015 at 20:29
  • 1
    @jackr BA is only insecure in the way you claim if you're using HTTP. Commented Mar 9, 2020 at 13:22

4 Answers 4

39

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)
Sign up to request clarification or add additional context in comments.

3 Comments

This comparison doesn't make any sense. Basic Auth is equivalent of putting the token in the header. https://my_token:@api.example.com will result in the header Authorization: Basic [base64-encoded-token-goes-here].
@sandstrom It may be functionally equivalent to just passing the username to Basic auth, but the point was to use a refreshable token instead of actual account credentials, and Authorization: Token makes that explicit. techblog.thescore.com/2014/06/25/…
API key in URL is the most performant option (no degradation whatsoever)
17

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.

6 Comments

I think OAuth would be too much for this kind of service. Why would you choose Basic Auth in this case?
in this case HTTP Basic Auth seems to me more elegant. Mainly because it is stardard and nobody needs to think something new.
This dangerous, given the URLs listed above are NOT https, but plain old http://. Anyone can use a tool like Firesheep to grab the API key and token, since Basic Auth does not provide any privacy for those credentials. You should only consider Basic Auth when used over https as most API providers do, including Github.
OAuth is required if you need to issue authorizations to 3rd parties (e.g. "valet keys") but I haven't seen many APIs implementing it solely for client-to-service access. Maybe that'll change as OAuth 2 gets more popular, but you're still asking users to do more work to connect.
how about using HTTPS Basic Auth? Isn't it far more secure than HTTP basic auth? Oauth requires you to make a few requests until you get the token
|
16

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...

1 Comment

SSL should be standard, so complexity in my opinion is not a consideration.
0

I would prefer using the token solution. If you don't have actual users with their own username and password, then it feels like you are using the Basic Auth construct not as intended. Not that that's necessarily wrong, but not as clean, IMO. It also removes the need to use custom headers and I think it makes implementation on both sides easier and cleaner. The next question I would be asking is if you should be using two-factor authentication or if you need to manage sessions at all.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.