-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify the description of REST vs OCS in accordance to sugestions discussed #12264
base: master
Are you sure you want to change the base?
Changes from all commits
71d81da
94c8694
0758bc0
4b76fec
ca6794c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,8 @@ REST APIs | |
|
||
.. sectionauthor:: Bernhard Posselt <dev@bernhard-posselt.com> | ||
|
||
Offering a RESTful API is not different from creating a :doc:`route <../basics/routing>` and :doc:`controllers <../basics/controllers>` for the web interface. It is recommended though to inherit from ApiController and add **@CORS** annotations to the methods so that `web applications will also be able to access the API <https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS>`_. | ||
Offering a RESTful API is not different from creating a :doc:`route <../basics/routing>` and :doc:`controllers <../basics/controllers>` for the web interface. | ||
It is recommended though to inherit from ApiController and add **@CORS** annotations to the methods so that `web applications will also be able to access the API <https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS>`_. | ||
Comment on lines
-9
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No relevant diff? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just styling to put every sentence on it's own line. I can drop that as well. |
||
|
||
.. code-block:: php | ||
|
||
|
@@ -44,7 +45,8 @@ CORS also needs a separate URL for the preflighted **OPTIONS** request that can | |
) | ||
|
||
|
||
Keep in mind that multiple apps will likely depend on the API interface once it is published and they will move at different speeds to react to changes implemented in the API. Therefore it is recommended to version the API in the URL to not break existing apps when backwards incompatible changes are introduced:: | ||
Keep in mind that multiple apps will likely depend on the API interface once it is published and they will move at different speeds to react to changes implemented in the API. | ||
Therefore it is recommended to version the API in the URL to not break existing apps when backwards incompatible changes are introduced:: | ||
Comment on lines
-47
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here |
||
|
||
/index.php/apps/myapp/api/1.0/resource | ||
|
||
|
@@ -79,3 +81,72 @@ To add an additional method or header or allow less headers, simply pass additio | |
} | ||
|
||
} | ||
|
||
.. _ocs-vs-rest: | ||
|
||
Relation of REST and OCS | ||
------------------------ | ||
|
||
There is a close relationship between REST APIs and :ref:`OCS <ocscontroller>`. | ||
Both provide a way to transmit data between the backend of the app in the Nextcloud server and some frontend. | ||
|
||
The following combinations of attributes might be relevant for various scenarios: | ||
|
||
#. Plain frontend route: ``Controller`` class | ||
#. Plain Frontend with CRSF checks disabled: ``Controller`` class and ``#[NoCSRFRequired]`` attribute on the method | ||
#. OCS-based route: ``OCSController`` class | ||
#. OCS-based route with CSRF disabled: ``OCSController`` class and ``#[NoCSRFRequired]`` attribute on the method | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this case doesn't exist, NoCSRFRequired should not have an effect on OCSController, but I will have to check that in the code to be sure. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking back and forth on this as well. In the end, I decided to keep the case as there is a certain difference (at least from the implementation): For methods with For the case where the attribute is not given, the strict cookie check boils down to a check on the With the header in place (as the OCS controller generally expects), the second part is also skipped: The CSRF check is hardcoded to true, thus When the header is not set, you enter the second if block and will check the inner if. The check I was adding this case as a reaction on your statement
In my opinion the last case could be dropped (and was never planned in the first round) but I do not see clearly the motivation of it, to be honest. Did I misunderstand your statement above? |
||
|
||
.. warning:: | ||
Adding the ``#[NoCRSFRequired]`` attribute imposes a security risk. | ||
You should not add this to your controller methods unless you understand the implications and be sure that you absolutely need the attribute. | ||
|
||
There are different ways a clients might interact with your APIs. | ||
These ways depend on your API configuration (what you allow) and on which route the request is finally made. | ||
|
||
- *Access from web frontend* means the user is browses the Nextcloud web frontend with a browser. | ||
- *Access from an external app* indicates that the user is not using the normal browser (as logged in) but directly navigates a certain URL. | ||
This can be in a new browser tab or an external program (like an Android app or simply a curl command line). | ||
|
||
.. list-table:: Comparison of different API types | ||
:header-rows: 1 | ||
:align: center | ||
|
||
* - Description | ||
- 1 (plain) | ||
- 2 (w/o CSRF) | ||
- 4 (OCS) | ||
- 4 (OCS w/o CSRF) | ||
* - URL prefix (relative to server) | ||
- ``/apps/<appid>/`` | ||
- ``/apps/<appid>/`` | ||
- ``/ocs/v2.php/apps/<appid>/`` | ||
- ``/ocs/v2.php/apps/<appid>/`` | ||
* - Access from web frontend | ||
- yes | ||
- yes (CSRF risk) | ||
- yes | ||
- yes (CSRF risk) | ||
* - Access from external app | ||
- --- | ||
- yes | ||
- yes (with header [#]_) | ||
- yes | ||
christianlupus marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* - Encapsulated data | ||
- no | ||
- no | ||
- yes (JSON or XML) | ||
- yes (JSON or XML) | ||
|
||
Methods from ``Controller`` classes can return ``DataResponse`` objects similar to ``OCSController`` class methods. | ||
For methods of a ``Controller`` class, the data of this response is sent e.g. as JSON as you provide it. | ||
Basically, the output is very similar to what ``json_encode`` would do. | ||
In contrast, the OCS controller will encapsulate the data in an outer shell that provides some more (meta) information. | ||
For example a status code (similar to the HTTP status code) is transmitted at top level. | ||
The actual data is transmitted in the ``data`` property. | ||
|
||
As a rule of thumb one can conclude that OCS provides a good way to handle most use cases including sufficient security checks. | ||
The only exception to this is if you want to provide an API for external usage where you have to comply with an externally defined API scheme. | ||
Here, the encapsulation introduced in OCS and CSRF checks might be in your way. | ||
|
||
.. [#] The OCS controller needs the request header ``OCS-APIREQUEST`` to be set to ``true``. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👀