Client Server API pattern in REST (unreliable network use case) - ruby-on-rails

Let's assume we have a client/server interaction happening over unreliable network (packet drop). A client is calling server's RESTful api (over http over tcp):
issuing a POST to http://server.com/products
server is creating an object of "product" resource (persists it to a database, etc)
server is returning 201 Created with a Location header of "http://server.com/products/12345"
! TCP packet containing an http response gets dropped and eventually this leads to a tcp connection reset
I see the following problem: the client will never get an ID of a newly created resource yet the server will have a resource created.
Questions: Is this application level behavior or should framework take care of that? How should a web framework (and Rails in particular) handle a situation like that? Are there any articles/whitepapers on REST for this topic?

The client will receive an error when the server does not respond to the POST. The client would then normally re-issue the request as they assume that it has failed. Off the top of my head I can think of two approaches to this problem.
One is that the client can generate some kind of request identifier, such as a guid, which it includes in the request. If the server receives a POST request with a duplicate GUID then it can refuse it.
The other approach is to PUT instead of POST to create. If you cannot get the client to generate the URI then you can ask the server to provide a new URI with a GET and then do a PUT to that URI.
If you search for something like "make POST idempotent" you will probably find a bunch of other suggestions on how to do this.

If it isn't reasonable for duplicate resources to be created (e.g. products with identical titles, descriptions, etc.), then unique identifiers can be generated on the server which can be tracked against created resources to prevent duplicate requests from being processed. Unlike Darrel's suggestion of generating unique IDs on the client, this would also prevent separate users from creating duplicate resources (which you may or may not find desirable). Clients will be able to distinguish between "created" responses and "duplicate" responses by their response codes (201 and 303 respectively, in my example below).
Pseudocode for generating such an identifier — in this case, a hash of a canonical representation of the request:
func product_POST
// the canonical representation need not contain every field in
// the request, just those which contribute to its "identity"
tags = join sorted request.tags
canonical = join [request.name, request.maker, tags, request.desc]
id = hash canonical
if id in products
http303 products[id]
else
products[id] = create_product_from request
http201 products[id]
end
end
This ID may or may not be part of the created resources' URIs. Personally, I'd be inclined to track them separately — at the cost of an extra lookup table — if the URIs were going to be exposed to users, as hashes tend to be ugly and difficult for humans to remember.
In many cases, it also makes sense to "expire" these unique hashes after some time. For example, if you were to make a money transfer API, a user transferring the same amount of money to the same person a few minutes apart probably indicates that the client never received the "success" response. If a user transfers the same amount of money to the same person once a month, on the other hand, they're probably paying their rent. ;-)

The problem as you describe it boils down to avoiding what are called double-adds. As mentioned by others, you need to make your posts idempotent.
This can be easily implemented at the framework level. The framework can keep a cache of completed responses. The requests have to have a request unique so that any retries are treated as such, and not as new requests.
If the successful response gets lost on its way to the client, the client will retry with the same request unique, the server will then respond with its cached response.
You are left with durability of the cache, how long to keep responses, etc. One approach is to remove responses from the server cache after a given period of time, this will depend on your app domain and traffic and can be left as a configurable step on the framework piece. Another approach is to force the client to sent acknowledgements. The acks can be sent either as separate requests (note that these could be lost too), or as extra data piggy backed on real requests.
Although what I suggest is similar to what others suggest, I strongly encourage you to keep this layer of network resiliency to do only that, deal with drop requests/responses and not allow it to deal with duplicate resources from separate requests which is an application level task. Merging both pieces will mush all functionality and will not leave you with a clear separation of responsibilities.
Not an easy problem, but if you keep it clean you can make your app much more resilient to bad networks without introducing too much complexity.
And for some related experiences by others go here.
Good luck.

As the other responders have pointed out, the basic problem here is that the standard HTTP POST method is not idempotent like the other methods. There is an effort underway to establish a standard for an idempotent POST method known as Post-Once-Exactly, or POE.
Now I'm not saying that this is a perfect solution for everybody in the situation you describe, but if it is the case that you are writing both the server and the client, you may be able to leverage some of the ideas from POE. The draft is here: https://datatracker.ietf.org/doc/html/draft-nottingham-http-poe-00
It isn't a perfect solution, which is probably why it hasn't really taken off in the six years since the draft was submitted. Some of the problems, and some clever alternate options are discussed here:
http://tech.groups.yahoo.com/group/rest-discuss/message/7646

HTTP is a stateless protocol, meaning the server can't open an HTTP connection. All connections get initialized by the client. So you can't solve such an error on the server side.
The only solution I can think of: If you know, which client created the product, you can supply it the products it created, if it pulls that information. If the client never contacts you again, you won't be able to transmit information about the new product.

Related

Communication with resources on a remote CSE - OneM2M

We are trying to implement the oneM2M standard and have a question regarding the communication process between Remote CSE and IN-CSE. I wrote what I understood from the documentation step by step in below. Some of the issues are not so clear for us so before doing any implementation, I need to make sure everything is crystal clear.
I going to ask the question before telling everything we understand from the documentation. Then I am going to write step by step what is the solution we think. The question is, the request which is sent by an IN-AE, is for MN-CSE which the IN-CSE should going to redirect the request to MN-CSE or it should handle it itself.
Before anything else, we have two absolutely separated CSEs. One is IN-CSE, the other one is MN-CSE almost like below.
IN-CSE has a resource tree
/in-cse61
/in-cse61/csr-34
/in-cse61/ae-1234
MN-CSE has a resource tree
/mn-cse34
/mn-cse34/csr-61
/mn-cse34/ae-123456
/mn-cse34/cnt-1
/mn-cse34/cin-01
/mn-cse34/cin-02
/mn-cse34/cin-03
/mn-cse34/cnt-2
We skipped any security concern for now. Let’s say IN-AE wants to communicate with MN-CSE as we told in question above.
1- IN-AE should send a discovery or retrieve request to IN-CSE saying that get me all the child resources Remote CSE.
2- What is the exact difference between sending discovery or sending retrieve request? We thought that discovery request returns just resource uri but retrieve request returns whole data of exact resource. Is this approach correct?
3- After getting all the remoteCSEs, now I know ids of the remoteCSEs'. Then I can send a discovery request to the MN-CSE to get AEs in it. We think two options:
a. ~/in-cse61/csr-34?fu=1&rty=2
b. ~/mn-cse34?fu=1&rty=2
Option a : If IN-AE only wants to make a discovery request for IN-CSE’s resource tree, IN-CSE should take care of it without redirecting it to the MN-CSE. Because IN-CSE already knows that /in-cse61/csr-34 is kind of a valid RemoteCSE for it but the request path starts with ~/in-cse61 then it should be handled by IN-CSE.
Option b: If IN-AE wants to make a discovery request for MN-CSE’s resource tree then IN-CSE can understand it is related a RemoteCSE by looking at the /mn-cse34 part of the Request path because it doesn’t startwith IN-CSE’s resourceid.
So IN-AE(ex. Smartphone) somehow should decide which CSE should handle the request ? Is there anything we think wrong ?
---------------------EDITED--------------------------------------
I have inspected architecture of Application Developer Guide TR-0025 http://www.onem2m.org/application-developer-guide/architecture
According to this sample, a smartphone (IN-AE) can control Light#1(ADN-AE-1) through IN-CSE.
After Registration and Initial Resource Creation processes are completed, system is ready to discover and then control the lights.
GET /~/mn-cse/home_gateway?fu=1&rty=3&drt=2 HTTP/1.1
Host: in.provider.com:8080
Although Middle Node CSE-ID and Middle Node CSEBase name is used at HTTP Request url, host is addressed to IN-CSE. It means, the discovery request sent from IN-AE, handled by IN-CSE first then it redirects it to mn-cse. However you told me the opposite by saying “The retrieval or discovery normally is only limited to the resources of the hosting CSE, and does not traverse to the remote CSEs automatically.”.
At TR-0025 the given example is shown as common scenario.
And also at TR-0034, Actually it is traversing the request as you see on the diagram.
There are many points in your question that needs to be addressed.
First of all, there is no special entity in oneM2M named "IN-AE". This is just the name that is used for the AE that connects to the IN-CSE in oneM2M's TR-0025 : Light control using HTTP binding developer guide. An Application Entity can actually be connected to an IN-CSE or an MN-CSE by the same protocol (mca), though there might be AEs that are especially designed to work on one particular CSE.
Regarding your point 2, the difference between a retrieve and a discovery request:
The retrieve request is targeted at a resource to retrieve it. For example, a retrieve request sent to the Container resource /mn-cse34/cnt-1 (from your example) would retrieve the Container resource itself and its attributes.
A discovery request is also be targeted at a resource, and technically it very much looks like a normal retrieve request. But in addition you provide filter criteria and discovery result type. For example, a discovery request sent to the same Container resource /mn-cse34/cnt-1 might return all the references to the ContentInstances from that Container resource. Depending on the filter and result type you can either get the full resources or only references to them.
Please have a look at oneM2M's specification TS-0001 Functional Architecture, sections 10.2.6 Discovery and 8.1.2 Request for a full explanation and the list of possible parameters for the discovery request.
Regarding points 1 and 3 of your question: I don't know what your AE wants to solve, but it should have a notion of the data structure build in. It is a good idea to organise the data in a structured and uniform way, e.g. by using Containers, FlexContainers, Groups etc. This way the application doesn't need to browse the whole resource tree of a CSE, which could become really big over time. Of course, it might be that it is a general application that needs to traverse over a bigger and prior unknown structure. In that case the application could use a discovery request to get the relevant resources. Please note, that you can also do discovery over meta-data of resources, e.g. labels, date and time etc. This might be helpful to reduce the result set.
The retrieval or discovery normally is only limited to the resources of the hosting CSE, and does not traverse to the remote CSEs automatically. An exception are announced resources. Those resources are announced to a remote CSE where they get a kind of "shadow" counterpart, and they provide your application some information about the state of the resources as well as to how to retrieve them (via a link attribute). But if you really want to access a remote CSE and your application has permissions to do so, the pointOfAccess attribute provides you with the address of the remote CSE.
But as said before, in general you application (AE) is connected to a single CSE. On that CSE all the resources of the AE, or the resources the AE has access to, are hosted. Also keep in mind that the AE needs to have permission (via an AccessControlPolicy) on the CSE to access the resource.
Update
Perhaps I need to elaborate a bit more on how to work with a remote CSE. Ignoring announced resource for now, there are two possibilities that your "IN-AE" can access a resource on the remote CSE:
You can send requests such as retrieve, update etc to the remote CSE resource in the IN-CSE. These requests are then forwarded to the real "mn-cse" instance by the Mcc connection between the IN-CSE and the MN-CSE. This has the advantage that the "IN-AE" doesn't need to care on how to connect to the MN-CSE "mn-cse" directly (e.g. there might be firewalls etc in place to protect the MN-CSE).
You can see this if you look at the HTTP Request in the example of TR-0025 (http://www.onem2m.org/application-developer-guide/implementation/content-instance-retrieve)
GET /~/mn-cse/home_gateway/light_ae1/light/la HTTP/1.1
This receiver of the http request is the IN-CSE. But, as you can see it targets a ContentInstance at the remote CSE mn-cse.
If you really need to access the remote CSE directly, for example for performance reasons, then your "IN-AE" can retrieve the pointOfAccess attribute and directly access the remote CSE "mn-cse". In that case the "IN-AE" actually becomes an AE of the remote CSE "mn-cse" and needs to know how to connect to it.

Handling overlapping asynchronous POST requests

We have implemented How to Use POST for Asynchronous Tasks in our project for long running tasks.
My question is how we can handle the case wherein we have multiple POST requests issued back-to-back from the same client. In this case, only the last POST request is what the client really is interested in. When a POST triggers a background thread, a subsequent POST also tries to trigger another background thread.
This effectively means that apart from the last POST request, the others result in wasteful computation
Are there any design patterns to address this?
I don't believe there is a commonly accepted pattern for this situation.
There are at least 2 situations where the duplicate POST can arise:
The client re-transmits the original POST for whatever reason ( such as it missed the response).
The user re-transmits either the original POST (intentionally or not) or he issues a new POST intended to replace the earlier versions.
It's best to deal with the problem at the server side.
One solution is to add a unique identifier (such as a GUID or a natural key) to each POST, and then have the server check if a request with that identifier already exists or not. Your server will need to save state somewhere while an existing POST is being processed (cookie, SESSION, local file, database are options) .
Note if you use a GUID you have to be sure that the client does not create a new GUID for re-transmits of the same request. You can avoid this problem by using a natural key instead of a GUID generator. The generation of the natural key should be repeatable and (reasonably) unique.

HTTPS POST Security level

I've searched for this a bit on Stack, but I cannot find a definitive answer for https, only for solutions that somehow include http or unencrypted parameters which are not present in my situation.
I have developed an iOS application that communicates with MySQL via Apache HTTPS POSTS and php.
Now, the server runs with a valid certificate, is only open for traffic on port 443 and all posts are done to https://thedomain.net/obscurefolder/obscurefile.php
If someone knew the correct parameters to post, anyone from anywhere in the world could mess up the database completely, so the question is: Is this method secure? Let it be known nobody has access to the source code and none of the iPads that run this software are jailbreaked or otherwise compromised.
Edit in response to answers:
There are several php files which alone only support one specific operation and depend on very strict input formatting and correct license key (retreived by SQL on every query). They do not respond to input at all unless it's 100% correct and has a proper license (e.g. password) included. There is no actual website, only php files that respond to POSTs, given the correct input, as mentioned above. The webserver has been scanned by a third party security company and contains no known vulnerabilities.
Encryption is necessary but not sufficient for security. There are many other considerations beyond encrypting the connection. With server-side certificates, you can confirm the identity of the server, but you can't (as you are discovering) confirm the identity of the clients (at least not without client-side certficates which are very difficult to protect by virtue of them being on the client).
It sounds like you need to take additional measures to prevent abuse such as:
Only supporting a sane, limited, well-defined set of operations on the database (not passing arbitrary SQL input to your database but instead having a clear, small list of URL handlers that perform specific, reasonable operations on the database).
Validating that the inputs to your handler are reasonable and within allowable parameters.
Authenticating client applications to the best you are able (e.g. with client IDs or other tokens) to restrict the capabilities on a per-client basis and detect anomalous usage patterns for a given client.
Authenticating users to ensure that only authorized users can make the appropriate modifications.
You should also probably get a security expert to review your code and/or hire someone to perform penetration testing on your website to see what vulnerabilities they can uncover.
Sending POST requests is not a secure way of communicating with a server. Inspite of no access to code or valid devices, it still leaves an open way to easily access database and manipulating with it once the link is discovered.
I would not suggest using POST. You can try / use other communication ways if you want to send / fetch data from the server. Encrypting the parameters can also be helpful here though it would increase the code a bit due to encryption-decryption logic.
Its good that your app goes through HTTPS. Make sure the app checks for the certificates during its communication phase.
You can also make use of tokens(Not device tokens) during transactions. This might be a bit complex, but offers more safety.
The solutions and ways here for this are broad. Every possible solution cannot be covered. You might want to try out a few yourself to get an idea. Though I Suggest going for some encryption-decryption on a basic level.
Hope this helps.

How to avoid Race Conditions when a restful architecture doesn't make sense

I'm making a website that I don't think makes sense to implement with a restful architecture (at least not the portion relevant to this problem), but it's causing some problems with race conditions across multiple servers which share a database.
My website has info about users of another product, so it has a Users table (not users of my site though). Users have many files.
Users and files are populated by an automated service, not manually on the site. The service posts the files to the server, the server parses them and gets the username from the file. If the username is new, it creates a new user row in the table. It then returns about the file to the service that made the request.
The problems I'm seeing are when race conditions when multiple requests come in at the same time for related objects, and it causes things like violations of unique indexes in the db.
For example, there is a unique key on username. This code can be a problem if 2 requests from the automated service for files from the same user come in at the same time.
var myuser = db.users.FirstOrDefault(u => u.username == username);
if(myuser == null)
{
myuser = new user(username);
db.AddObject(user);
}
db.SaveChanges();
Request 1 will see that there is no user with username foo, so the if condition returns true. Request 2 sees the same thing, not knowing that request 1 already began creating the user, and when request 2 tries to save, it violates the unique key.
Is there a common pattern or solution to this problem? I know this wouldn't be a problem if the server was RESTful, but I don't think it's really feasible for the service to change the way it makes requests, so I'd like that to stay the same if possible. Right now, it just posts the file to the server, not knowing whether the user of that file existed already, or whether that file was posted to the server yet (it may post it more than once). Those objects are created if they don't exist yet, and if they do, the list of items is updated. But as far the service is concerned, it just wants to know certain info about the file, and isn't concerned with whether or not it already exists in my db.
I think it'd be too slow for it to try to create a user via a request, then try to create the file via a request, and then request info about the file in another request. Also, the service runs multiple requests at a time via Parallel.ForEach, and it'd be too slow for it to run it in a single thread.
The first thing is separation of concerns. If you have an automated service populating the data, then that service (or another piece of middleware) should be responsible for creating the database records. This shouldn't happen at run time in response to a request to your website.
Second, if you must do it this way, that is what locks are for. Each request to your website runs in it's own thread(s). So, if multiple threads need to access the same volatile resource (your DB) then you need to institute optimistic locking, so that the first thread in wins and any further threads will only be able to try to interact with that table or row (depending on the type of lock) once the first has completed its work.
Third, this is pretty much exactly what RESTful architecture attempts to solve. You can use ETags to version your resources so any attempt to POST to an outdated resource will return an HTTP error (409 Conflict) directing the client to refetch the original resource.

Implementing a 2 Legged OAuth Provider

I'm trying to find my way around the OAuth spec, its requirements and any implementations I can find and, so far, it really seems like more trouble than its worth because I'm having trouble finding a single resource that pulls it all together. Or maybe it's just that I'm looking for something more specialized than most tutorials.
I have a set of existing APIs--some in Java, some in PHP--that I now need to secure and, for a number of reasons, OAuth seems like the right way to go. Unfortunately, my inability to track down the right resources to help me get a provider up and running is challenging that theory. Since most of this will be system-to-system API usage, I'll need to implement a 2-legged provider. With that in mind...
Does anyone know of any good tutorials for implementing a 2-legged OAuth provider with PHP?
Given that I have securable APIs in 2 languages, do I need to implement a provider in both or is there a way to create the provider as a "front controller" that I can funnel all requests through?
When securing PHP services, for example, do I have to secure each API individually by including the requisite provider resources on each?
Thanks for your help.
Rob, not sure where you landed on this but wanted to add my 2 cents in case anyone else ran across this question.
I more or less had the same question a few months ago and hearing about "OAuth" for the better part of a year. I was developing a REST API I needed to secure so I started reading about OAuth... and then my eyes started to roll backwards in my head.
I probably gave it a good solid day or 2 of skimming and reading until I decided, much like you, that OAuth was confusing garbage and just gave up on it.
So then I started researching ways to secure APIs in general and started to get a better grasp on ways to do that. The most popular way seemed to be sending requests to the API along with a checksum of the entire message (encoded with a secret that only you and the server know) that the server can use to decide if the message had been tampered with on it's way from the client, like so:
Client sends /user.json/123?showFriends=true&showStats=true&checksum=kjDSiuas98SD987ad
Server gets all that, looks up user "123" in database, loads his secret key and then (using the same method the client used) re-calculates it's OWN checksum given the request arguments.
If the server's generated checksum and the client's sent checksum match up, the request is OK and executed, if not, it is considered tampered with and rejected.
The checksum is called an HMAC and if you want a good example of this, it is what Amazon Web Services uses (they call the argument 'signature' not 'checksum' though).
So given that one of the key components of this to work is that the client and server have to generate the HMAC in the same fashion (otherwise they won't match), there have to be rules on HOW to combine all the arguments... then I suddenly understood all that "natural byte-ordering of parameters" crap from OAuth... it was just defining the rules for how to generate the signature because it needed to.
Another point is that every param you include in the HMAC generation is a value that then can't be tampered with when you send the request.
So if you just encode the URI stem as the signature, for example:
/user.json == askJdla9/kjdas+Askj2l8add
then the only thing in your message that cannot be tampered with is the URI, all of the arguments can be tampered with because they aren't part of the "checksum" value that the server will re-calculate.
Alternatively, even if you include EVERY param in the calculation, you still run the risk of "replay attacks" where a malicious middle man or evesdropped can intercept an API call and just keep resending it to the server over and over again.
You can fix that by adding a timestamp (always use UTC) in the HMAC calculation as well.
REMINDER: Since the server needs to calculate the same HMAC, you have to send along any value you use in the calculation EXCEPT YOUR SECRET KEY (OAuth calls it a consumer_secret I think). So if you add timestamp, make sure you send a timestamp param along with your request.
If you want to make the API secure from replay attacks, you can use a nonce value (it's a 1-time use value the server generates, gives to the client, the client uses it in the HMAC, sends back the request, the server confirms and then marks that nonce value as "used" in the DB and never lets another request use it again).
NOTE: 'nonce' are a really exact way to solve the "replay attack" problem -- timestamps are great, but because computers don't always have in-sync timestamp values, you have to allow an acceptable window on the server side of how "old" a request might be (say 10 mins, 30 mins, 1hr.... Amazon uses 15mins) before we accept or reject it. In this scenario your API is technically vulnerable during the entire window of time.
I think nonce values are great, but should only need to be used in APIs that are critical they keep their integrity. In my API, I didn't need it, but it would be trivial to add later if users demanded it... I would literally just need to add a "nonce" table in my DB, expose a new API to clients like:
/nonce.json
and then when they send that back to me in the HMAC calculation, I would need to check the DB to make sure it had never been used before and once used, mark it as such in the DB so if a request EVER came in again with that same nonce I would reject it.
Summary
Anyway, to make a long story short, everything I just described is basically what is known as "2-legged OAuth". There isn't that added step of flowing to the authority (Twitter, Facebook, Google, whatever) to authorize the client, that step is removed and instead the server implicitly trusts the client IF the HMAC's they are sending match up. That means the client has the right secret_key and is signing it's messages with it, so the server trusts it.
If you start looking around online, this seems to be the preferred method for securing API methods now-adays, or something like it. Amazon almost exactly uses this method except they use a slightly different combination method for their parameters before signing the whole thing to generate the HMAC.
If you are interested I wrote up this entire journey and thought-process as I was learning it. That might help provide a guided thinking tour of this process.
I would take a step back and think about what a properly authenticated client is going to be sending you.
Can you store the keys and credentials in a common database which is accessible from both sets of services, and just implement the OAuth provider in one language? When the user sends in a request to a service (PHP or Java) you then check against the common store. When the user is setting up the OAuth client then you do all of that through either a PHP or Java app (your preference), and store the credentials in the common DB.
There are some Oauth providers written in other languages that you might want to take a look at:
PHP - http://term.ie/oauth/example/ (see bottom of page)
Ruby - http://github.com/mojodna/sample-oauth-provider
.NET http://blog.bittercoder.com/PermaLink,guid,0d080a15-b412-48cf-b0d4-e842b25e3813.aspx

Resources