Skip to content

Commit 05e3cfc

Browse files
Adding some text on historic routing with REST routes
Signed-off-by: Christian Wolf <[email protected]>
1 parent 033311e commit 05e3cfc

File tree

1 file changed

+81
-29
lines changed

1 file changed

+81
-29
lines changed

developer_manual/digging_deeper/rest_apis.rst

Lines changed: 81 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -89,75 +89,76 @@ Relation of REST and OCS
8989

9090
There is a close relationship between REST APIs and :ref:`OCS <ocscontroller>`.
9191
Both provide a way to transmit data between the backend of the app in the Nextcloud server and some frontend.
92+
This is explicitly not about :ref:`HTML template responses <controller_html_responses>`.
93+
94+
State-of-the-Art methods and comparison
95+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9296

9397
The following combinations of attributes might be relevant for various scenarios:
9498

9599
#. Plain frontend route: ``Controller`` class
96-
#. Plain frontend with CRSF checks disabled: ``Controller`` class and ``#[NoCSRFRequired]`` attribute on the method
97-
#. Plain frontend route with CORS enabled: ``Controller`` class and ``#[CORS]`` and ``#[NoCSRFRequired]`` attributes on the route
98100
#. OCS route: ``OCSController`` class
99101
#. OCS route with CORS enabled: ``OCSController`` class and ``#[CORS]`` attribute on the method
100102

101103
.. warning::
102104
Adding the ``#[NoCRSFRequired]`` attribute imposes a security risk.
103105
You should not add this to your controller methods unless you understand the implications and be sure that you absolutely need the attribute.
106+
Typically, you can instead use the ``OCS-APIRequest`` header for data requests, instead.
104107

105108
.. warning::
106-
Adding the attribute ``#[CORS]`` alone is not sufficient to allow access using CORS.
107-
The CSRF checker will typically fail, so enabling CORS enforces you to disable the CSRF checker as well.
108-
Although the disabled CSRF checker in itself is a security issue to consider, adding CORS opens up this even more.
109-
You should make sure, that you understand the implications completely when enabling CORS and do so only when there is a good use case.
109+
Adding the attribute ``#[CORS]`` alone is not sufficient to allow access using CORS with plain frontend routes.
110+
Without further measures, the CSRF checker would fail.
111+
So, enabling CORS for plain controllers is generally and highly discouraged.
112+
113+
You would have to disable the CSRF checker (one more security risk) or use the ``OCP-APIRequest`` header to successfully pass the checker.
114+
The latter requires dedicated JS code on the importing page.
110115

111116
There are different ways a clients might interact with your APIs.
112117
These ways depend on your API configuration (what you allow) and on which route the request is finally made.
113118

114119
- *Access from web frontend* means the user is browses the Nextcloud web frontend with a browser.
115-
- *Access from an external app* indicates that the user is not using the normal browser (as logged in) but directly navigates a certain URL.
116-
This can be in a new browser tab or an external program (like an Android app or simply a curl command line).
120+
- *Access from an external app* indicates that the user is not using the normal browser (as logged in) but directly navigates a certain URL directly.
121+
This is typically an external program (like an Android app or simply a curl command line).
117122
- *Access from external website* means that the user browses some third party web site and data from your Nextcloud server appears.
118123
The other website has to embed/load/use images, JSON data, or other resources from a URL pointing to the Nextcloud server, to be able to do this.
119124

125+
.. hint::
126+
The discussion here is for data requests only.
127+
If you think of controller :ref:`methods serving (HTML) templates <controller_html_responses>`, disabling CSRF is considered fine.
128+
120129
.. list-table:: Comparison of different API types
121130
:header-rows: 1
122131
:align: center
123132

124133
* - Description
125-
- 1 (plain)
126-
- 2 (w/o CSRF)
127-
- 3 (CORS)
128-
- 4 (OCS)
129-
- 5 (OCS+CORS)
134+
- ``Controller`` class
135+
- ``OCSController`` class
136+
- ``OCSController`` class & ``CORS`` on method
130137
* - URL prefix (relative to server)
131-
- ``/apps/<appid>/``
132-
- ``/apps/<appid>/``
133138
- ``/apps/<appid>/``
134139
- ``/ocs/v2.php/apps/<appid>/``
135140
- ``/ocs/v2.php/apps/<appid>/``
136141
* - Access from web frontend
137142
- yes
138-
- yes (CSRF risk)
139-
- yes (CSRF risk)
140143
- yes
141-
- yes (CSRF risk [#]_)
142-
* - Access from external app
143-
- ---
144144
- yes
145+
* - Access from external app
146+
- partial [#]_
145147
- yes
146-
- yes (with header [#]_)
147148
- yes
148149
* - Access from external website
149150
- ---
150151
- ---
151152
- yes
152-
- ---
153-
- yes
154153
* - Encapsulated data
155-
- no
156-
- no
157154
- no
158155
- yes (JSON or XML)
159156
- yes (JSON or XML)
160157

158+
.. [#] The external app has to satisfy the CSRF checks.
159+
That is, you need to have the ``OCS-APIRequest`` HTTP request header set to ``true``.
160+
This is only possible for NC 30 onwards, older versions do not respect the header.
161+
161162
Methods from ``Controller`` classes can return ``DataResponse`` objects similar to ``OCSController`` class methods.
162163
For methods of a ``Controller`` class, the data of this response is sent e.g. as JSON as you provide it.
163164
Basically, the output is very similar to what ``json_encode`` would do.
@@ -169,7 +170,58 @@ As a rule of thumb one can conclude that OCS provides a good way to handle most
169170
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.
170171
Here, the encapsulation introduced in OCS and CSRF checks might be in your way.
171172

172-
.. [#] Only if you have set ``#[NoCSRFRequired]``.
173-
OCS controllers have other CSRF checks in place that work with CORS without disabling the CSRF checks completely.
174-
Using the ``OCS-APIRequest`` header is a CSRF protection which is compatible with CORS.
175-
.. [#] The OCS controller needs the request header ``OCS-APIRequest`` to be set to ``true``.
173+
174+
Historical options
175+
~~~~~~~~~~~~~~~~~~
176+
177+
.. deprecated:: 30
178+
The information in this section are mainly for reference purposes. Do not use the approaches in new code.
179+
180+
Before NC server 30 the plain ``Controller`` classes' methods did not respect the ``OCS-APIRequest`` header.
181+
Thus, to provide access to this type of controller methods for external apps, it was necessary to use the ``#[NoCSRFRequired]`` attribute (or the corresponding ``@NoCSRFRequired`` annotation).
182+
183+
The following combinations of attributes were relevant for various scenarios:
184+
185+
#. Plain frontend route: ``Controller`` class
186+
#. Plain frontend with CRSF checks disabled: ``Controller`` class and ``#[NoCSRFRequired]`` attribute on the method
187+
#. Plain frontend route with CORS enabled: ``Controller`` class and ``#[CORS]`` and ``#[NoCSRFRequired]`` attributes on the route
188+
#. OCS route: ``OCSController`` class
189+
#. OCS route with CORS enabled: ``OCSController`` class and ``#[CORS]`` attribute on the method
190+
191+
.. hint::
192+
The two scenarios involving the ``OCSController`` have not changed and, thus, the state-of-the-art documentation as noted above still holds true.
193+
Thus, these options are not reconsidered here again for simplicity reasons and to get the overall view more crisp.
194+
195+
The warnings about not using ``NoCSRFRequired`` and ``CORS`` as mentioned in the state-of-the-art section holds true here as well.
196+
197+
.. list-table:: Comparison of different API types
198+
:header-rows: 1
199+
:align: center
200+
201+
* - | Description
202+
- | ``Controller`` class
203+
- | ``Controller`` class with
204+
| ``NoCSRFRequired`` on method
205+
- | ``Controller`` class with
206+
| ``NoCSRFRequired`` and ``CORS``
207+
| on method
208+
* - URL prefix (relative to server)
209+
- ``/apps/<appid>/``
210+
- ``/apps/<appid>/``
211+
- ``/apps/<appid>/``
212+
* - Access from web frontend
213+
- yes
214+
- yes (CSRF risk)
215+
- yes (CSRF risk)
216+
* - Access from external app
217+
- ---
218+
- yes
219+
- yes
220+
* - Access from external website
221+
- ---
222+
- ---
223+
- yes
224+
* - Encapsulated data
225+
- no
226+
- no
227+
- no

0 commit comments

Comments
 (0)