I've created a small wishlist project.
I wan't to serve an API for users, which have an API Key.
My webserver run on TLS (HTTPS). It is safe for users to send api key in clear in the http headers like that ?
curl -H "Authorization: api_key MY_APP_API_KEY" https://myapp.example.com
Otherwise, what should I use ?
I would like not to use OAuth2, which is too complex for my little project.
Yes it is perfectly safe.. HTTPS encrypts all message contents, including the HTTP headers and the request/response data.
Is this a Web product?
If so, keep in mind your MY_APP_API_KEY will be fully available in the browser.
If it is a Web product, maybe consider a simple alternative like https://pay2my.app for logins (I'm involved in that OSS project)? Users login browser-side and send their own token + signature to the server: server just validates that.
Otherwise you're already good to go as per the first answer đź‘Ť.
Related
Is it possible to just use cURL to handle the authentication with the Xero API for a private application? I've played with the PHP library and that all works well but I'd like to just use straight cURL commands for the HTTP Requests which it can obviously do, just not sure if I can use cURL to handle the OAuth 1.0a authentication?
If you happen to use Filemaker Pro you can do this easily via the BaseElements plugin from Goya using BE_Xero_SetTokens, and then including the consumer key and your private key as the username and password in subsequent HTTP requests.
Details here.
I'm working on writing API for web-project. For identifying API users basic authentication is used. And in order to test API call I can use curl command line tool and write something like this:
curl -H "Authorization: Basic Tm9TY1hETjRGNjIwZ1FwcTZOMENjMHczSjJDTjFlcnM6VmhWM21kUHF1MkIyMjFDaWRKVE4odyYmbyRpTEBsM0U=" http://example.com/api/function
On the test server we have HTTP authentication. I've uploaded scripts with API functionality and now I don't understand how I can make call to the API function on the test server. How I can provide username and password for HTTP authentication and after provide username and password for API?
Basically, you are trying to perform two authentications in a row, with the same method. This is not a scenario covered by [this authentication protocol][1]---so in short, you cannot with standard settings.
The reason why the protocol cannot cater with this scenario is a header clash: The first challenge will use the WWW-Authenticate / Authorization header pair, as well as the second in a single request.
One way to allow for a double authentication requires changes (that you may not be allowed to do):
You could have the first authentication process accept two pairs of headers, authenticate against the first one, and then rewrite the headers for the second authentication process. This should be fine for a test environment, provided the environment contains no security-sensitive data, e.g. customer data. Absolutely a bad idea otherwise.
You could replace the first authentication process by a different protocol. For example, you could deactivate the process and require an SSH / VPN tunnel to access the machine. Then, all HTTP requests could be tunneled and they would just need to authenticate against the second process.
One final thing. I did not know this would not work:
curl --user "test:password" http://stan:uberflow#myserver.com
Both --user and the credentials in the URL use basic authentication, so they step on each other. It may depend on the implementation; in my environment --user has precedence.
[1]: I carefully avoided to say security protocol, as HTTP Basic Authentication is not "very" secure, and it offers poor protection over HTTPS.
I'm constructing an application with 2 sides: client (iPhone) and Server (PHP). Communication using https. The mobile phone gets a 4SQ access token. Then, it sends that token to the server, and the server will make 4SQ API calls using it. My question is about how to send this token.
My idea was to include the token in the HTTP Authentication request's header, but after reading about basic/digest authentication, I suspect it isn't the way of doing it. Actually, the calls to 4SQ API are done using a request parameter
oauth_token=ACCESS_TOKEN
instead of putting the token in Authentication header, or any other place. I'm sure there's a good reason for that, but I can't find it.
Then, which option is the best?
Phone sends token to PHP server as request parameter, like 4SQ does
Phone sends token to PHP server in Authentication header (which kind oh authentication is?)
Any other way
Many thanks in advance, and best regards
I think the most secure and reasonable way would be a HTTPS POST. When the token is part of the query string in a HTTPS request, it is also encrypted. But it will appear clear text in the server log, or, when a browser is used, it could also appear in the browser history. Depending on the HTTP helper library, it could also log the HTTPS URL, when, for example, a request fails.
In my eyes, sending the token in the Authentication header would be strange, since it is not used for authentication between the server and the client.
I want to create a flexible API Rest server. I will allow the clients to authenticate using HTTP or an APIKEY.
My question is: what is the correct way to add the apikey to a GET request? My problem is the apikey pollutes the url.
I imagine something like this : /book/1/apikey/s4cr4t !
In my opinion you should only use the Authorization header. That's what it is there for.
Putting it in the URL is a bad idea because:
a) as you said it pollutes the URL
b) if you decide to go SSL for security then the API will still appear in log files
c) caches will end up creating multiple copies of the same representation, one for each api key.
For more information on creating your own Authorization scheme go here.
Credentials may be passed using the Authorization header:
GET http://domain.com:/book/1
Authorization: apikey="s4cr4t"
It all depends on how far you want to go but the mechanics stays the same:
Context
The goal is to identify the client with some level of security. (Note: Security is another detailed discussion). Remember that one if the “features” of REST is to be stateless: That means no session state on the server except for resources. To keep the client stateless, it needs to supply on each request enough information that the request is independent. It must give the server a way to identify the client such as a username/password, API Key or token.
You have various options to do this so here are some:
Add HTTP headers to identify the client
Here one can use the Authorization header and send it with each request. There are various authentication schemes but stick to the standard ones such as Basic Auth. Here you would probably stick to SSL. The authentication process generates a kind of token if you like.
You can also make use of a cookie. The cookie must contain no information except that it is a “pointer or key” to a stateful session resource on your server (note: session it a resource which is “rest-legal”). You can create this resource by doing a PUT (+info) with response 200 OK or POST (+info) with a response of 201 Created and Location: /sessions/123334. The session can then be validated by the server such as timeout, valid client ip address, api key etc.
With the method above, you can also define a customer header such as Api-Key: XXXX. But then you limit yourself to special client. Set-Cookie are “well known” headers so browser will handle them kind of transparently. The authentication process can then be done by following links and filling in forms (PUT + POST) to authenticate (create session resource).
Encode an identifier in the content
Here you are free to do what you want too. Just add a field/token/id to your content and let the server verify it.
A RESTful API does application flow by resolving links. See also HATEOAS and Fielding's words. This also applies when you have a separate process of logging in to the application.
Do not encode any data in the URIs. (Out of band information)
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?
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)
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...
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.
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.