I designed APIs in php using SLIM framework. I can access these APIs like this:
http://192.168.1.210/getSchool
This API is used to get information about schools. I am using these APIs in my android application. Now I want to make security of my these APIs. so no one can access these APIs with out authentication means no one can get list of schools by just entering the above URL in address bar.
I want that user first log in using my android application then he or she can use my api, no one can directly access in my apis.
Please give me your valuable suggestion.
Thank you in advance.
Once a user is registered with your application, you can generate & assign them an API key in the database (perhaps a hash) which you can return to the phone. Each time the phone sends a request to the API it also sends across their API key which you can validate against their database entry.
This should also all be done over SSL to avoid MITM attacks/viewing of API keys.
There are also other methods available: Looking for suggestions for building a secure REST API within Ruby on Rails (language agnostic).
You should create UID and a secret key for each user when they sign up and store on the server. And pass these to the user using https initially. The user will store these two values(make sure secret key is kept safely).
When the user want to send a api request he will create the request url then hashes it using the secret key + timestamp and addes the UID, hash and timestamp to the request and sends to the server.
The server extract the UID then gets the secret from db and then generated the hash of the request (without UID, hash and timestamp) using secret key + timestamp param.
if the hash generated and the hash param from the url matches proceed with the request or ignore it.
Or
Implement OAuth
Related
A quick question about API Keys with PHP/MYSQL. I have been doing a lot of reading over the last few days but just need further clarification and some best practice guidelines as I am only very new with HTML, JS, JQUERY, PHP / MYSQL.
My server side code is PHP, which connects to the MYSQL database. The database has a users table which will store columns such as id, username, password (which uses password_hash() via PHP5 so it does not store the plaintext value) and api_key. I will also look at adding some such as last_seen and last_login for further security.
I would like the API Key to be used to authenticate the user to access resources on the server (eg. parseID.php, which takes POST arguments to return a JSON result on the ID's the user enters). The user can use this API key in a script as well to access the JSON output if required.
My thought process is:
An already logged in user clicks a button to generate an API key.
The script generates an API key (Using password_hash()) and saves it against the user ID in the database
When a user wants to access a protected resource, they will provide the given API key in the GET/POST (or stored in a session??) which will attempt to match it with the one in the database and return the result (Auth VS Not Auth).
If authenticated, The User is able to access the resource.
I will also use SSL to encrypt the traffic between the user / resource.
I am a little unclear and wondering what other steps / best practices can be taken here to ensure that the API key and the users information is safe?
All of the information I have searched on here and on google is a few years old and using practices such as MD5 to encrypt the keys.
Thanks!
This is correct - the API key is assigned to the user and calls are required to pass the API in order to authenticate the user and check what they can do.
Some changes I'd suggest:
An already logged in user clicks a button to generate an API key.
If the user can only have one API key, it will be easier for you and users to just generate the API key when the account is created and make it available in their profile/settings area (i.e. make it a one-to-one relationship rather than one-to-zero-or-one). The only reason you'd want to generate it on demand is if you have to give explicit permission, e.g. through some moderation process.
Either way, you will also want to let users reset the API key (mainly in case of a possible leak).
BTW a more common pattern is to support multiple API keys. e.g. if you look at Twitter's developer dashboard, a user can create N "apps" and each app automatically gets its own API key. There are some advantages to this approach, e.g. you can gather metadata around the apps, API keys are partitioned (better security), permissioning models can be different for each app, and you can revoke a single app without affecting all usages. All that may be overkill for you though.
stored in a session??
Session is more of a web concept related to cookies being passed back and forth. You don't need that complication. It should be easy enough just to require the API key in every request path.
When a user wants to access a protected resource
You may as well require the API key in every request, not just those for protected resources. It should be just as easy for the user anyway, and it will let you do things like rate-limit and log requests on a per-user basis.
I need to create a REST api to authenticate a user the first time and retrieve other information based on this user for subsequent calls. If I'm not mistaken Restful services are stateless and therefore there is no need to store user information server side. My question is how can I guarantee user authentication for all the subsequent calls without a session?
This service is needed to create an android app that can display information on mobile.
You could use OAuth which is a widely used standard.
Another option is to use BASIC authentication over SSL. Any decent HTTP library would support BASIC auth. The client will be challenged the first time the request is made. Subsequent request need to send the BASIC auth headers over a secure line.
The there is the approach where you pass a secret to your client and use HMAC-SHA256 to send a hash of the URL params over to the server. Amazon does that and there is an article that covers how this is done. It is not as complicated as OAuth.
There are many approaches available but IMO your best best is to generate a AuthToken server side and return that to the client upon successful login. Then the client includes this on every request down to the server.
What I typical do is create a MD5 hash of a secret key and the the user's id- user's username - user's password - and the current date time. Then I store the token and the current date time in the db. on look ups after that I decode the token and compare the data points against the db values and if they match the user is good. This way is stateless and easily scalable.
I created a REST API and implemented a Signature system as a layer of security, basically how it works is that I have API users that connect to the API using a secret key(lets say a password) that only the user and the API know, then after a session is open the API return an API key to be used for all subsequent calls.
All subsequents call will provide the API key and a sha256 hash of the different request parameters, hash created using the secret key.
So far so good, however I am facing a problem where I have a full AJAX client calling the API, but I don't want my users to type their username and password(secret key) everytime they want to open a session and get a new API Key if they previously connected to the API in the past.
Temporarily, I am storing the secret key in plain text in a cookie using javascript but it seems wrong to me.
Do you guys have suggestions or links to point me too? Is there something I don't understand?
Thanks in advance!
Give them a hashed lease on the API. A lease grants them access to the API for a certain amount of time, and that time is specified in the token. For example, it could be good for the next 7 days. You can do this by simply adding the end date to your token and signing it.
When the app goes back to try and start a new session, it can ask the server to give it a new lease, assuming they're already authenticated, good for another 7 days.
If they try to access the server after 7 days, then they need to re-authenticate.
I've read about oAuth, Amazon REST API, HTTP Basic/Digest and so on but can't get it all into "single piece". This is probably the closest situation - Creating an API for mobile applications - Authentication and Authorization
I would like to built API-centric website - service. So (in the beginning) I would have an API in center and website (PHP + MySQL) would connect via cURL, Android and iPhone via their network interfaces. So 3 main clients - 3 API keys. And any other developer could also develop via API interface and they would get their own API key. API actions would be accepted/rejected based on userLevel status, if I'm an admin I can delete anything etc., all other can manipulate only their local (account) data.
First, authorization - should I use oAuth + xAuth or my some-kind-of-my-own implemenation (see http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/RESTAuthentication.html?r=9197)? As I understand, on Amazon service user is == API user (have API key). On my service I need to separate standard users/account (the one who registered on the website) and Developer Accounts (who should have their API key).
So I would firstly need to authorize the API key and then Authenticate the user itself. If I use Amazon's scheme to check developer's API keys (authorize their app), which sheme should I use for user authentication?
I read about getting a token via api.example.org/auth after (via HTTPS, HTTP Basic) posting my username and password and then forward it on every following request. How manage tokens if I'm logged in simultaneously on Android and a website? What about man-in-the-middle-attack if I'm using SSL only on first request (when username and password are transmitted) and just HTTP on every other? Isn't that a problem in this example Password protecting a REST service?
As allways, the best way to protect a key is not to transmit it.
That said, we typically use a scheme, where every "API key" has two parts: A non-secret ID (e.g. 1234) and a secret key (e.g. byte[64]).
If you give out an API key, store it (salted and hashed) in you
service's database.
If you give out user accounts (protected by password), store the
passwords (salted and hashed) in your service's database
Now when a consumer first accesses your API, to connect, have him
Send a "username" parameter ("john.doe" not secret)
Send a "APIkeyID" parameter ("1234", not secret)
and give him back
the salts from your database (In case one of the parameters is wrong,
just give back some repeatable salt - eg.
sha1(username+"notverysecret").
The timestamp of the server
The consumer should store the salt for session duration to keep things fast and smooth, and he should calculate and keep the time offset between client and server.
The consumer should now calculate the salted hashes of API key and password. This way the consumer has the exact same hashes for password and API key, as what is stored in your database, but without anything seceret ever going over the wire.
Now when a consumer subseqently accesses your API, to do real work, have him
Send a "username" parameter ("john.doe" not secret)
Send a "APIkeyID" parameter ("1234", not secret)
Send a "RequestSalt" parameter (byte[64], random, not secret)
Send a "RequestTimestamp" parameter (calculated from client time and known offset)
Send a "RequestToken" parameter (hash(passwordhash+request_salt+request_timestamp+apikeyhash))
The server should not accept timestamps more than say 2 seconds in the past, to make this safe against a replay attack.
The server can now calculate the same hash(passwordhash+request_salt+request_timestamp+apikeyhash) as the client, and be sure, that
the client knows the API key,
the client knows the correct password
I have a PHP web application that I want to make accessible across multiple clients. So, I'm trying to make it more like an API. My question is: How would I handle the creation of new users using the API? If I have a URL like http://example.com/user/signup which takes new user details and creates a new user via a POST request, wouldn't it be a problem that people can misuse it and create fake users easily?
i would recommend only allowing open id in the API, as it would be hard to implement bot preventing schemes into it (captcha ...)
anyway even open id isint that a great idea in the API are you sure you need registration available thru the API ?
What you need to do is use something like OAuth to authenticate access to your system from registered 'apps'. Then the clients can register for access and receive a token key and secret. Then they can use these things to create a request for an access token. Both parties sign the token using the secret and then they can use the encrypted access token to hit the API. Your server verifies the incoming token using the secret that only you and the authorized clients could have. Now it's secure.