API key for WebView does not work

In my Gnome shell extension, I now use an API key to connect to the syncthing daemon REST API. I would like to use the same API key for connecting a simple WebView to the daemon, just like SyncTrayzor is doing it. I found an old fixed issue about it, so this should just work out of the box.

I added the proper X-API-Key header to the HTTP request. A test with netcat shows that the header line is successfully sent over the TCP connection, and the API key is in fact correct. So it should just connect without any additional authentication, right?

However, it does not. When I add a username and password to syncthing, the REST API still connects successfully to the daemon, but the WebView does not. It asks for a username and a password.

Any hint what I am doing wrong?

To investigate this further, I sniffed the HTTP traffic that is exchanged between the extension and syncthing.

tcpflow: listening on lo
127.000.000.001.34334-127.000.000.001.08387: GET / HTTP/1.1
Host: 127.0.0.1:8387
Accept-Encoding: identity
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/602.1 (KHTML, like Gecko) Version/8.0 Safari/602.1
X-API-Key: iHoMhgjsHU3dK1UZRsKf6Mu1lN4kzULd
Accept-Language: en-us
Connection: Keep-Alive


127.000.000.001.08387-127.000.000.001.34334: HTTP/1.1 200 OK
Content-Length: 40986
Content-Type: text/html
X-Syncthing-Id: REDACTD-REDACTD-REDACTD-REDACTD-REDACTD-REDACTD-REDACTD-REDACTD
X-Syncthing-Version: v0.13.7
Date: Sat, 25 Jun 2016 08:35:20 GMT

<!DOCTYPE html>
<!--
// Copyright (C) 2014 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.

-->
<html lang="en" ng-app="syncthing" ng-controller="SyncthingController" class="ng-cloak">
... // content truncated ...
</html>

127.000.000.001.34334-127.000.000.001.08387: GET /vendor/bootstrap/css/bootstrap.css HTTP/1.1
Host: 127.0.0.1:8387
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/602.1 (KHTML, like Gecko) Version/8.0 Safari/602.1
Accept: text/css,*/*;q=0.1
Referer: http://127.0.0.1:8387/
Accept-Encoding: gzip, deflate
Accept-Language: en-us
Connection: Keep-Alive


127.000.000.001.08387-127.000.000.001.34342: HTTP/1.1 401 Unauthorized
Content-Type: text/plain; charset=utf-8
Www-Authenticate: Basic realm="Authorization Required"
X-Content-Type-Options: nosniff
Date: Sat, 25 Jun 2016 08:35:20 GMT
Content-Length: 15

Not Authorized

You can see that the first HTTP message is sent correctly with a correct X-API-Key: header line, and syncthing responds with an HTTP message without any Www-Authenticate: header line. The subsequent HTTP message from the extension, however, do not contain a proper X-API-Key: header line, and thus syncthing answers with a Not Authorized message.

I wonder why in the first response there is no Set-Cookie: header. Shouldn’t there be at least two (sessionid-... and CSRF-Token)?

Cookies/CSRF are not used if authentication is done via API Key, as you are using programmatic API which is not guaranteed to support cookies or parsing CSRF tokens.

The framework I am using does support Cookies, but AFAIK it cannot add additional headers (i.e. X-API-Key) to subsequent resource requests. It is only the initial URL request that I can modify :frowning:

So there is no way to make this work?

Not really. Alternatively, you can embed basic auth in the URL.

That issue was closed, because the OP had a way to force the X-API-Key header for every request.

Another way, that could work, is to point the webview to https://username:password@127.0.0.1:8387/ which should implicitly login to the basic auth which will then return the session and CSRF cookie.

Ok, I will consider using username/password instead of the API key, although I must admit that this does not sound very appealing.

Anyways, thank you both for your help. :slight_smile: