webapppassword
webapppassword copied to clipboard
cors error on file sharing apis (OCS)
Explain the Problem
i have problem with using share api . doument tells we should use /apps/webapppassword/api/v1/shares instead /ocs/v2.php/apps/files_sharing/api/v1/shares as far as i found out. when i use /apps/webapppassword/api/v1/shares OPTIONS request is ok but i got cors error on request itself (POST) and when i use /ocs/v2.php/apps/files_sharing/api/v1/shares i get method not allowed error on OPTIONS request. currently im using webapppassword and i have no problem with webdav apis im using these apis in same project . how to call share apis without cors error
Steps to Reproduce
this is my axios call
const response = await axios.post(
'http://nc.develop/apps/webapppassword/api/v1/shares',
{
path: 'welcome.txt',
shareType: 0, // 3 represents "user" share type, change it based on your requirements
shareWith: 'sina',
permissions: 19,
password: "admin",
attributes:""
},
{
headers:{
"Authorization": "Bearer "+localStorage.getItem("access_token"),
"authorization": "Bearer "+localStorage.getItem("access_token"),
}
}
);
console.log('Share created:', response.data);
} catch (error) {
console.error('Error creating share:', error.message);
}
System Information
- WebAppPassword app version: 23.6.0
- Nextcloud version: 26.0.3
- PHP version: 8.1.2
Contents of nextcloud/data/nextcloud.log
nothing adds in log
Contents of Browser Error Console
Access to XMLHttpRequest at 'http://nextcloud_proxy_backend.develop/apps/webapppassword/api/v1/shares' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
@aleixq (#61)
@aleixq (#61)
is that bug right?
I'll take a look asap. I've got it working using the webdav picker. Let me check and compare requests and responses.
I couldn't reproduce...
Just inspecting a little and as I said I have it working using webdav-filepicker (patching a file to change the share endpoint url to the webapppassord one).
When creating a share it will send a preflight automatically to check the access-control options:
fetch("https://nextcloud/index.php/apps/webapppassword/api/v1/shares", {
"headers": {
"accept": "*/*",
"accept-language": "ca-ES,ca;q=0.9",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site"
},
"referrer": "https://cms-site.org/",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": null,
"method": "OPTIONS",
"mode": "cors",
"credentials": "omit"
});
This call must return
Access-Control-Allow-Credentials: false
Access-Control-Allow-Headers: Authorization, Content-Type, Accept, OCS-APIRequest
Access-Control-Allow-Methods: PUT, POST, GET, DELETE, PATCH
Access-Control-Allow-Origin: https://cms-site.org
Access-Control-Max-Age: 1728000
Cache-Control: no-cache, no-store, must-revalidate
Content-Length: 0
Content-Security-Policy: default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'
Content-Type: text/html; charset=UTF-8
Feature-Policy: autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'
Pragma: no-cache
Referrer-policy: no-referrer
X-Content-Type-Options: nosniff
X-Debug-Message: debug-msg 3
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-Robots-Tag: noindex, nofollow
X-Robots-Tag: none
X-Xss-Protection: 1; mode=block
(Where the relevant ones are the Access-control ones)
After that a regular post request to https://nextcloud/index.php/apps/webapppassword/api/v1/shares is sent.
If you paste the options request headers and repsonse maybe I could help a little more... Also maybe check https://github.com/axios/axios/issues/4712 similar issue? Or maybe the server is blocking OPTIONS request?
@aleixq yes i copied your fetch request in my code its status code is 200 for options request and header of response is exactly you said
at the moment for my api call like create share i get cors error on post request not option as i check network/xhr section of browser and i have no problem with axios for not send option request about an issue that you share because response of option request is 200. for reproduce this is my code that get cors error on post request:
const response = await axios.post(
'http://nextcloud_proxy_backend.develop/apps/webapppassword/api/v1/shares',
{
path: 'welcome.txt',
shareType: 0,
shareWith: 'sina',
permissions: 19,
password: "admin",
attributes:""
},
{
headers:{
// "OCS-APIREQUEST": true,
"Authorization": "Bearer "+localStorage.getItem("access_token"),
"authorization": "Bearer "+localStorage.getItem("access_token"),
}
}
);
console.log('Share created:', response.data);
} catch (error) {
console.error('Error creating share:', error.message);
}
mention that this is error in console:
`Access to XMLHttpRequest at 'http://nextcloud_proxy_backend.develop/apps/webapppassword/api/v1/shares' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.`
Could you please paste using "add collapsible content" button in this editor the request and response headers of OPTIONS and POST ? you could use next as template: ---- START of TEMPLATE ----
OPTIONS headers request
paste content
here
OPTIONS headers response
paste content
here
POST headers request
paste content
here
POST headers response
paste content
here
---- END of TEMPLATE ----
These headers will help a lot determining if the origins check is made as it should (logics are in https://github.com/digital-blueprint/webapppassword/pull/61/files#diff-e9996f62a46f389c1d8031d1020d33d4a97c47db07606c0ad730eb7d0b88e7de if you want to help debugging it)
About the issue itself, Is 'http://localhost:8080' among the allowed origins?
OPTIONS headers request
OPTIONS /apps/webapppassword/api/v1/shares HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: authorization,content-type
Access-Control-Request-Method: POST
Cache-Control: no-cache
Connection: keep-alive
Host: nextcloud_proxy_backend.develop
Origin: http://localhost:8080
Pragma: no-cache
Referer: http://localhost:8080/
Sec-Fetch-Mode: cors
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
OPTIONS headers response
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Thu, 20 Jul 2023 09:57:45 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Connection: keep-alive
Set-Cookie: oc_sessionPassphrase=xlCi5N5zOuR6s0V%2FonFRz8yr9jS3BnINfHLYhBB5ti9jcH7iC4fomsS%2BstH3lyIaZkJyOP4Zl2BauokFUCKKrVkpj1MktyC%2FwEoy%2ButxTMOkN7gVTmmK%2BVuMvE6VaJkc; path=/; HttpOnly; SameSite=Lax
Set-Cookie: nc_sameSiteCookielax=true; path=/; httponly;expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax
Set-Cookie: nc_sameSiteCookiestrict=true; path=/; httponly;expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict
Set-Cookie: ocn93pv6mvl1=jlv8jbcbjmckukfihakl57grk8; path=/; HttpOnly; SameSite=Lax
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Cache-Control: no-cache, no-store, must-revalidate
X-Request-Id: uyhhV8hxuQ5QD2QAP5gx
Access-Control-Allow-Origin: http://localhost:8080
Access-Control-Allow-Methods: PUT, POST, GET, DELETE, PATCH
Access-Control-Max-Age: 1728000
Access-Control-Allow-Headers: Authorization, Content-Type, Accept, OCS-APIRequest
Access-Control-Allow-Credentials: false
Content-Security-Policy: default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'
Feature-Policy: autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'
X-Robots-Tag: noindex, nofollow
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Robots-Tag: none
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
POST headers request
POST /apps/webapppassword/api/v1/shares HTTP/1.1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Authorization: Bearer 4wzjwHlqtsMPQbhwpEYvJ1UXICetLpwhN1TKCEHmqWKq7VNT6jNJMmwOz6caIZNeQpKJ8PBR
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 107
Content-Type: application/json
Host: nextcloud_proxy_backend.develop
Origin: http://localhost:8080
Pragma: no-cache
Referer: http://localhost:8080/
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
POST headers response
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Thu, 20 Jul 2023 09:57:45 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 138
Connection: keep-alive
Set-Cookie: oc_sessionPassphrase=o9XowNurZX4ExunllF0B9M%2FDkyjhn2T%2F2eD3tG7sQUnUoF%2BHZbLnTnRwN83nRfcmLfEjCira%2FjDpryMnuSNcRhaLMEUTSDrRlFq21Lm12yBVHdLGPa2fBsEuMWGiPeBH; path=/; HttpOnly; SameSite=Lax
Set-Cookie: nc_sameSiteCookielax=true; path=/; httponly;expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax
Set-Cookie: nc_sameSiteCookiestrict=true; path=/; httponly;expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict
Set-Cookie: ocn93pv6mvl1=559tbndl46embtvknhia242g01; path=/; HttpOnly; SameSite=Lax
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Cache-Control: no-cache, no-store, must-revalidate
X-Request-Id: hXD9cNBQwxDtqtFYynP4
Content-Security-Policy: default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'
Feature-Policy: autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'
X-Robots-Tag: noindex, nofollow
Content-Encoding: gzip
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Robots-Tag: none
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
i added to allow origins 'http://localhost:8080' like webdav section @aleixq
Why did you comment the OCS-APIRequest header in your axios post? Could you please check setting this to true.
Let's test but i think this is the cause. Despite it is not a regular OCS endpoint request it needs these set to true as this method is inherited from an ocs endpoint. And as documentation says in https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html :
All calls to OCS endpoints require the OCS-APIRequest header to be set to true.
@aleixq i tested it previously so i comment that now i checked that with header again but still cors error and nothing changes .
post request headers
POST /apps/webapppassword/api/v1/shares HTTP/1.1Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Authorization: Bearer o6Q3QzP4pnVxg4AajbwMEiNM6x6CvT7TmI9nuJCudR1a3toJO95AFVTFNA7G8GPeH9LEKc7Q
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 107
Content-Type: application/json
Host: nextcloud_proxy_backend.develop
OCS-APIRequest: true
Origin: http://localhost:8080
Pragma: no-cache
Referer: http://localhost:8080/
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
post response headers
HTTP/1.1 200 OKServer: nginx/1.18.0 (Ubuntu)
Date: Thu, 20 Jul 2023 23:48:16 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 138
Connection: keep-alive
Set-Cookie: oc_sessionPassphrase=opmQ2VV5KTnXj47I01jCNTj48wL6xXDcFvHkx6yqpJMs5%2Bqjz6cvae9oXF%2B1%2FMfB%2BTFB21BIcdsdwsYKDh%2BoCCACd38reRTZOHiYIoGRxoy5cNd0HmrnO04YY0uLAbff; path=/; HttpOnly; SameSite=Lax
Set-Cookie: nc_sameSiteCookielax=true; path=/; httponly;expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax
Set-Cookie: nc_sameSiteCookiestrict=true; path=/; httponly;expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict
Set-Cookie: ocn93pv6mvl1=tnqsg3vs2pn21o5g6qbmb5l4db; path=/; HttpOnly; SameSite=Lax
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Cache-Control: no-cache, no-store, must-revalidate
X-Request-Id: QlqpT8U9jL1FgI8gR7eX
Content-Security-Policy: default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'
Feature-Policy: autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'
X-Robots-Tag: noindex, nofollow
Content-Encoding: gzip
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Robots-Tag: none
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Well. Let's check another thing. Did you test with basic auth rather than bearer ?
@aleixq i tested it and not worked too when everything is ok its error is cors error. i think this can be helpful when i enable cors extension on chrome it works correctly but the problem is when i enable cors extension, web dav apis get cors error and and no longer works.
I don't know if i am understanding... Could you use punctuation? So the problem appears when using a chrome extension?
@aleixq no no . im working with webdav apis and share apis without enabling cors extension . with disable cors extension webdav apis works correctly and share apis get cors error but if you enable cors extension, share apis will works but webdav apis get cors error. i know cors extension should be disabled, for getting any clue and for test i just enabled it
@aleixq if we comment the section of header set in webapppassword/lib/Controller/AccessControl.php still option request of share api is 204 and it seems not has any effect but if we comment setCorsHeaders in webapppassword/lib/Connector/Sabre/CorsPlugin.php webdav apis get cors error so CorsPlugin.php works correctly and has effect
i think set header for share apis has problem and not trigger at all
@aleixq if we comment the section of header set in
webapppassword/lib/Controller/AccessControl.phpstill option request of share api is 204 and it seems not has any effect but if we commentsetCorsHeadersinwebapppassword/lib/Connector/Sabre/CorsPlugin.phpwebdav apis get cors error soCorsPlugin.phpworks correctly and has effect i think set header for share apis has problem and not trigger at all
Let me create a simple manual test case to evaluate if there's something wrong(asap). What is true is that I have it working fine with nextcloud-webdav-filepicker both webdav and share api. While test is not made you can check it out with this filepicker (you must change the endpoint url to point to webapppassword filesharing endpoint url)
@aleixq im using webapppassword filesharing endpoint as code already posted here and im looking at nextcloud-webdav-filepicker codes and to be honest i didnt find any useful tip . now i added these headers temporary in first line of ShareApiController and now works but as you know this way is not ok
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Max-Age: 86400');
Hi again, I have created some manual tests in https://gitlab.com/communia/nc-webapppassword-share-test . They are ran as it should... Could you test to see if fails in your case ? note that I am using fetch api so not axios directly. The readme.md explains everything. More users and environments tests are welcome to find errors...
I see another issue but not in our domain: a thing that must be reviewed is that share api call to native files_sharing endpoint is not allowed but is executed and share is created... despite cors origin failing... So share is created but no response text can be used in script because of cors.