Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h1>Updated Answer</h1> <p>Addressing your questions (as opposed than going off on a bit of a tangent in my original answer :D), here's my opinions:</p> <p>1) My main opinion on this is that I dislike <code>d</code>. As a client consuming the API I would find it confusing. What does it even stand for anyway? data? </p> <p>The other options look good. <code>Columns</code> is nice because it mirrors back to the user what they requested.</p> <p>If you are doing pagination, then another option might be something like <code>page</code> or <code>slice</code> as it makes it clear to the client, that they are not receiving the entire contents of the collection.</p> <pre><code>{ "offset": 0, "limit": 100, "page" : [ ... ] } </code></pre> <p>2) TBH, I don't think it makes that much difference which way you go for this, however if it was me, I probably wouldn't bother sending back the envelope, as I don't think there is any need (see below) and why make the request structure any more complicated than it needs to be? </p> <p>I think POSTing back the envelope would be odd. POST should let you add items into the collection, so why would the client need to post the envelope to do this?</p> <p>PUTing the envelope back could make sense from a RESTful standpoint as it could be seen as updating metadata associated with the collection as a whole. I think it is worth thinking about the sort of meta data you will be exposing in the envelope. All the stuff I think would fit well in this envelope (like pagination, aggregations, search facets and similar meta data) is all read only, so it doesn't make sense for the client to send this back to the server. If you find yourself with a lot of data in the envelope that the client is able to mutate - then it could be a sign to break that data out into a separate resource with the list as a sub collection. Rubbish example:</p> <p><code>/animals</code></p> <pre><code>{ "farmName": "farm", "paging": {}, "animals": [ ... ] } </code></pre> <p>Could be broken up into:</p> <p><code>/farm/1</code></p> <pre><code>{ "id": 1, "farmName": "farm" } </code></pre> <p>and</p> <p><code>/farm/1/animals</code></p> <pre><code>{ "paging": {}, "animals": [ ... ] } </code></pre> <p>Note: Even with this split, you could still return both combined as a single response using something like <a href="https://developers.facebook.com/docs/reference/api/field_expansion/" rel="nofollow noreferrer">Facebook's</a> or <a href="http://developer.linkedin.com/documents/field-selectors" rel="nofollow noreferrer">LinkedIn's</a> field expansion syntax. E.g. <code>http://example.com/api/farm/1?field=animals.offset(0).limit(10)</code> </p> <p>In response, to your question about how the client should know what the JSON payload they are POSTing and PUTing should look like - this should be reflected in your API documentation. I'm not sure if there is a better tool for this, but <a href="http://swagger.wordnik.com/" rel="nofollow noreferrer">Swagger</a> provides a spec that allows you to document what your request bodies should look like using <a href="http://en.wikipedia.org/wiki/JSON#Schema" rel="nofollow noreferrer">JSON Schema</a> - check out <a href="https://github.com/wordnik/swagger-core/wiki/datatypes" rel="nofollow noreferrer">this page</a> for how to define your schemas and <a href="https://github.com/wordnik/swagger-core/wiki/parameters" rel="nofollow noreferrer">this page</a> for how to reference them as a parameter of type <code>body</code>. Unfortunately, Swagger doesn't visualise the request bodies in it's fancy web UI yet, but it's is open source, so you could always add something to do this. </p> <h1>Original Answer</h1> <p>Check out <a href="http://haacked.com/archive/2009/06/24/json-hijacking.aspx#84979" rel="nofollow noreferrer">William's</a> comment in the discussion thread on that page - he suggests a way to avoid the exploit altogether which means you can safely use a JSON array at the root of your response and then you need not worry about either of you questions.</p> <p>The exploit you link to relies on your API using a Cookie to authenticate a user's session - just use a query string parameter instead and you remove the exploit. It's probably worth doing this anyway since using Cookies for authentication on an API isn't very RESTful - some of your clients may not be web browsers and may not want to deal with cookies.</p> <h2>Why Does this fix work?</h2> <p>The exploit is a form of CSRF attack which relies on the attacker being able to add a <code>script</code> tag on his/her own page to a sensitive resource on your API. </p> <pre><code>&lt;script src="http://mysite.com/api/columns"&gt;&lt;/script&gt; </code></pre> <p>The victims web browser will send all Cookies stored under <code>mysite.com</code> to your server and to your servers this will look like a legitimate request - you will check the <code>session_id</code> cookie (or whatever your server-side framework calls the cookie) and see the user is authenticated. The request will look like this:</p> <pre><code>GET http://mysite.com/api/columns Cookie: session_id=123456789; </code></pre> <p>If you change your API you ignore Cookies and use a session_id query string parameter instead, the attacker will have no way of tricking the victims web browser into sending the session_id to your API.</p> <p>A valid request will now look like this:</p> <pre><code>GET http://mysite.com/api/columns?session_id=123456789 </code></pre> <p>If using a JavaScript client to make the above request, you could get the session_id from a cookie. An attacker using JavaScript from another domain will not be able to do this, as you cannot get cookies for other domains (<em><a href="https://stackoverflow.com/questions/8834436/how-to-get-cookies-from-a-different-domain-with-php-and-javascript#tab-top">see here</a></em>). </p> <p>Now we have fixed the issue and are ignoring session_id cookies, the script tag on the attackers website will still send a similar request with a GET line like this:</p> <pre><code>GET http://mysite.com/api/columns </code></pre> <p>But your server will respond with a <code>403 Forbidden</code> since the GET is missing the required session_id query string parameter. </p> <h1>What if I'm not authenticating users for this API?</h1> <p>If you are not authenticating users, then your data cannot be sensitive and anyone can call the URI. CSRF should be a non-issue since with no authentication, even if you prevent CSRF attacks, an attacker could just call your API server side to get your data and use it in anyway he/she wants. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. CO+1 Thanks for a thorough response and taking the time to explain the pros and cons in depth. While I'm fully hypermedia and all that and could start emitting session-specific links, I'd like to reiterate that I have no beef with having to embed arrays in a property - and agree with @tuespetre that it can actually be a more understandable / Pit of Successy design. My question is centred around a) what do people do on the GET side (esp the naming and/or whether to lean on the a specific `application/json-?/` Media Type w/ JSON) and b) does the PUT/POST side ever vary wrt having a root node
      singulars
    2. COAh sure. I really should have read your comments from yesterday on the question. I also agree that wrapping arrays in an object can be a good idea - we are planning to do this on the REST API we're currently working on, and not just for arrays at the root of the document, but for all arrays throughout. Our main reason was to provide a place for pagination meta data for each array in the document.
      singulars
    3. COGood point re having somewhere for the metadata to live. I'm using HAL, and your point is relevant to that, though having `{_embedded { Tags: { Items: [ {"Id": 1, "Desc": "desc"}], _metadata1; 2 }}}` gets pretty ugly fast. I'm leaning by instinct towards a YAGNI there (having said that [in HAL] having an extra layer allows `_links` for the collection to have a home... Another point for people to consider in their answers (or to ask on the HAL mailing list)
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload