I have a couchdb server, which at this moment is for development and it has just one node running in docker.
I would like to authenticate through JWT. I have build my token.
GET https://comp010:6984/_session
Accept: application/json
Content-Type: application/json; charset=utf-8
Authorization: Bearer <JWT token>
I get proper answer (or at least I think so):
{
"ok": true,
"userCtx": {
"name": "uaru",
"roles": "admin"
},
"info": {
"authentication_handlers": [
"jwt",
"cookie",
"default"
],
"authenticated": "jwt"
}
}
When I send request to get actual object from the database
GET https://comp010:6984/db_userspaces/xxxx3
Accept: application/json
Content-Type: application/json; charset=utf-8
I get "unauthorized" exception. This is ok, I did not authenticated this request. So I add the same authorization header:
GET https://comp010:6984/db_userspaces/xxxx3
Accept: application/json
Content-Type: application/json; charset=utf-8
Authorization: Bearer <JWT token>
And I get
{
"error": "internal_server_error",
"reason": "No DB shards could be opened.",
"ref": 179462285
}
But if I switch off the authorization ( [chttpd] require_valid_user = false), and send the same request without Authorization header,
GET https://comp010:6984/db_userspaces/xxxx3
Accept: application/json
Content-Type: application/json; charset=utf-8
I get proper response.
Server: CouchDB/3.2.1 (Erlang OTP/23)
X-Couch-Request-ID: 02c628ce15
X-CouchDB-Body-Time: 0
{
"_id": "xxxx3",
"_rev": "1-a11f390ffa77a03c557ffbbc7c5fda75",
"x": "1"
}
How JWT can relate to shards? I am puzzled and I cannot find anything related.
There are no errors with Fauxton.
Thank you in advance for any suggestions.
Here is the log when the request took place
couchdb-server_1 | [error] 2022-03-09T04:52:34.662593Z nonode#nohost <0.6234.1> 82a6b79f38 rexi_server: from: nonode#nohost(<0.6134.1>) mfa: fabric_rpc:open_shard/2 error:function_clause [{lists,usort,[<<"admin">>],[{file,"lists.erl"},{line,1063}]},{couch_db,check_security,3,[{file,"src/couch_db.erl"},{line,713}]},{couch_db,is_authorized,2,[{file,"src/couch_db.erl"},{line,705}]},{couch_db,is_member,1,[{file,"src/couch_db.erl"},{line,685}]},{couch_db,check_is_member,1,[{file,"src/couch_db.erl"},{line,671}]},{couch_db,open,2,[{file,"src/couch_db.erl"},{line,166}]},{mem3_util,get_or_create_db,2,[{file,"src/mem3_util.erl"},{line,549}]},{fabric_rpc,open_shard,2,[{file,"src/fabric_rpc.erl"},{line,307}]}]
couchdb-server_1 | [error] 2022-03-09T04:52:34.662982Z nonode#nohost <0.6236.1> 82a6b79f38 rexi_server: from: nonode#nohost(<0.6134.1>) mfa: fabric_rpc:open_shard/2 error:function_clause [{lists,usort,[<<"admin">>],[{file,"lists.erl"},{line,1063}]},{couch_db,check_security,3,[{file,"src/couch_db.erl"},{line,713}]},{couch_db,is_authorized,2,[{file,"src/couch_db.erl"},{line,705}]},{couch_db,is_member,1,[{file,"src/couch_db.erl"},{line,685}]},{couch_db,check_is_member,1,[{file,"src/couch_db.erl"},{line,671}]},{couch_db,open,2,[{file,"src/couch_db.erl"},{line,166}]},{mem3_util,get_or_create_db,2,[{file,"src/mem3_util.erl"},{line,549}]},{fabric_rpc,open_shard,2,[{file,"src/fabric_rpc.erl"},{line,307}]}]
couchdb-server_1 | [error] 2022-03-09T04:52:34.663440Z nonode#nohost <0.6134.1> 82a6b79f38 req_err(179462285) internal_server_error : No DB shards could be opened.
couchdb-server_1 | [<<"fabric_util:get_shard/4 L118">>,<<"fabric_util:get_shard/4 L132">>,<<"fabric:get_security/2 L183">>,<<"chttpd_auth_request:db_authorization_check/1 L112">>,<<"chttpd_auth_request:authorize_request/1 L19">>,<<"chttpd:handle_req_after_auth/2 L325">>,<<"chttpd:process_request/1 L310">>,<<"chttpd:handle_request_int/1 L249">>]
couchdb-server_1 | [notice] 2022-03-09T04:52:34.663753Z nonode#nohost <0.6134.1> 82a6b79f38 comp010:6984 ::ffff:150.26.121.46 uaru GET /db_userspaces/xxxx3 500 ok 2
In the payload to be turned into JWT, roles MUST BE an array.
{
:sub => username,
:'_couchdb.roles' => roles,
:exp => ...,
}
In my case, roles was not. But it means that should be error 400 Bad Request.
The whole problem has nothing to do with shards configuration, etc. The error message was misleading.
Thanks to people in CouchDb slack channel for guiding me in the right direction.
I'm trying to access JSON data (in R) from a REST API.
To authenticate myself, I need to use a POST method in https://dashboard.server.eu/login. The data that needs to be sent are email and password:
library(httr)
login <- list(
email = "my#email.com",
password = "mypass"
)
res <- POST("https://dashboard.server.eu/login", body = login, encode = "form", verbose())
When executing the above, I get this output:
-> POST /login HTTP/1.1
-> Host: dashboard.server.eu
-> User-Agent: libcurl/7.59.0 r-curl/3.3 httr/1.4.1
-> Accept-Encoding: gzip, deflate
-> Cookie: session=10kq9qv1udf0107F4C70RY14fsum41sq50
-> Accept: application/json, text/xml, application/xml, */*
-> Content-Type: application/x-www-form-urlencoded
-> Content-Length: 53
->
>> email=my%40email.com&password=mypass
<- HTTP/1.1 200 OK
<- access-control-allow-headers: Accept, Authorization, Content-Type, If-None-Match
<- access-control-allow-methods: HEAD, GET, POST, PUT, DELETE
<- cache-control: no-cache
<- content-encoding: gzip
<- content-type: application/json; charset=utf-8
<- date: Mon, 09 Mar 2020 14:58:31 GMT
<- set-cookie: session=10kq9qv1udf0107F4C70RY14fsum41sq50; HttpOnly; SameSite=Strict; Path=/
<- vary: origin,accept-encoding
<- x-microserv: NS4yNi4xODQuMjE3
<- x-poweredby: Poetry
<- Content-Length: 2346
<- Connection: keep-alive
The doc of the site says that, in case of success, a JSON res is returned and contains a string token in res.data._id.
I don't find it... even looking at every list (and sub-lists) of res.
How am I supposed to find the token?
Following the doc, and an example in AngularJS, I'm then supposed to do:
// Create JSON Object with your token
let authorizeObject = {
'Authorization': 'Session ' + token,
'content-type': 'application/json;charset=UTF-8',
'accept': 'application/json,text/plain',
};
// Create header from the previous JSON Object
let header = {'headers':authorizeObject};
// Use the header in your http request...
$http.get('https://dashboard.server.eu/', header)
Any hint on making this dream become true?
UPDATE -- With cURL, I could check that there is a _id key/value returned…
With the command:
curl -k -X POST "https://dashboard.server.eu/login" \
-d '{ "email" : "my#email.com", "password" : "mypass" }' \
-H "Content-Type: application/json"
I get the output:
{
"_id": "697v2on4ll0107F4C70RYhosfgtmhfug",
"isAuthenticated": true,
"user": {
"_id": "5dd57868d83cfc000ebbb273",
"firstName": "me",
"lastName": "Me",
...
So, the session token is indeed somewhere...
Does this help to help me?
Looking at the image of res in your question, the message is there, under content - it's just that the content is stored as a vector of raw bytes, which is why you didn't recognise it as json.
Since any file type can be sent by http, the contents in an httr response object are stored in raw format rather than a character string for various reasons - perhaps most importantly because many binary files will contain a 0x00 byte, which isn't allowed in a character string in R.
In your case, we can not only tell that res$content is text, but that it is your "missing" json. The first six bytes of res$content are shown in your image, and are 7b, 22, 5f, 69, 64, 22. We can convert these to a character string in R by doing:
rawToChar(as.raw(c(0x7b, 0x22, 0x5f, 0x69, 0x64, 0x22)))
[1] "{\"_id\""
This matches the first six characters of your expected json string.
Therefore if you do:
httr::content(res, "text")
or
rawToChar(res$content)
You will get your json as a character string.
When making requests to the Google OAuth2 API according to their documentation/guide, I keep getting 401 Unauthorized responses from https://accounts.google.com/oauth2/v4/token even though I swear I'm giving all the required fields:
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
User-Agent: curl/7.47.0
Accept: */*
Content-Length: 311
Content-Type: application/x-www-form-urlencoded
client_id=REDACTED
&client_secret=REDACTED
&code=REDACTED
&grant_type=authorization_code
&redirect_uri=https%3A%2F%2Flocalhost%2Fsso%3Fredirect%3D%252F
Response:
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Vary: X-Origin
Vary: Referer
Date: Wed, 03 Jul 2019 16:14:15 GMT
Server: scaffolding on HTTPServer2
Cache-Control: private
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Alt-Svc: quic=":443"; ma=2592000; v="46,43,39"
Accept-Ranges: none
Vary: Origin,Accept-Encoding
Transfer-Encoding: chunked
{
"error": "invalid_client",
"error_description": "Unauthorized"
}
I've checked and triple-checked my client_id, client_secret, authorized hosts and redirect_uri, and looked through similar problems on stack overflow, but nothing seems to work... why is this happening to me :(
It's because Google's guide/documentation are lying to you. That's not the right endpoint, and instead of saying so, it's giving you that extremely unhelpful error message. Hopefully, they'll be made aware of this SO post/answer and fix it. To find out the actual URL to use to obtain an authorization token, you can click on the "Download JSON" button on your credentials' view page on console.developers.google.com, instead of just copy/pasting the client_id and client_secret. Then you'll get something that looks like this:
{
"web": {
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"client_id": "REDACTED",
"client_secret": "REDACTED",
"javascript_origins": [
"https://localhost"
],
"project_id": "REDACTED",
"redirect_uris": [
"https://localhost/sso?redirect=%2F"
],
"token_uri": "https://oauth2.googleapis.com/token"
}
}
and there you have it. The REAL token URI.
I need to send simple HTTP POST Request using ESP8266. It's containing data in "form-data".
It should look like this:
POST http://testserver.com
{
"auth_key":"key",
"data":[
{
"key":"temperature",
"value":31.2
},
{
"key":"humidity",
"value":50
}
]
}
For the testing I was using Chrome application - Postman. And the HTTP Request code which I send was looking like this (it was automatically generated):
POST /api/mes HTTP/1.1
Host: testserver.com
Cache-Control: no-cache
Postman-Token: 9b910ed2-afdc-2a11-4963-2f85626cfa4e
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="auth_key"
79bde0ff1efeaee90b1e432c08d324ecfdb532ac42406d7a9a87dd911e95f87e
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="data"
[{"key":"humidity", "value":55}]
------WebKitFormBoundary7MA4YWxkTrZu0gW--
And through Postman everything was okay. So then I sent it through ESP8266:
client.setNoDelay(true);
client.println("POST /api/mes HTTP/1.1");
client.println("Host: testserver.com");
client.println("Cache-Control: no-cache");
client.println("Postman-Token: 9b910ed2-afdc-2a11-4963-2f85626cfa4e");
client.println("Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
client.println("");
client.println("------WebKitFormBoundary7MA4YWxkTrZu0gW");
client.println("Content-Disposition: form-data; name=\"auth_key\"");
client.println("");
client.println("79bde0ff1efeaee90b1e432c08d324ecfdb532ac42406d7a9a87dd911e95f87e");
client.println("------WebKitFormBoundary7MA4YWxkTrZu0gW");
client.println("Content-Disposition: form-data; name=\"data\"");
client.println("");
client.println("[{\"key\":\"humidity\", \"value\":55}]");
client.println("------WebKitFormBoundary7MA4YWxkTrZu0gW--");
But unfortunately server is returning that the request is not correct. What can cause the problem? I'm struggling with it but I don't have any more ideas.
I have written a POST route in Express.js: /api/file/upload. This route needs two parameters to work - a "file" parameter with the posted file and an "apiKey" parameter, which is a string. To test it, I am trying to create a successful request in Fiddler2 with the following data:
Headers:
Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468
User-Agent: Fiddler
Host: localhost:8000
Content-Length: 178037
Request Body:
---------------------------acebdf13572468
Content-Disposition: form-data; name="file"; filename="4Byl64P (1).jpg"
Content-Type: image/jpeg
<#INCLUDE *C:\Users\patrick\Pictures\4Byl64P (1).jpg*#>
---------------------------acebdf13572468--
---------------------------acebdf13572468
Content-Disposition: form-data; name="apiKey"
Content-Type: application/json
{
"apiKey": "GKBG-QoNs-f74E-Z8Qn-zozm"
}
---------------------------acebdf13572468--
But when I try to log the parameters in Node.js, I get an empty object for request.body and undefined for request.files.
How do I successfully POST form data to Node.js using Fiddler2?
Your body is malformed (premature ending boundary). It should probably look more like this:
---------------------------acebdf13572468
Content-Disposition: form-data; name="apiKey"
Content-Type: application/json
{
"apiKey": "GKBG-QoNs-f74E-Z8Qn-zozm"
}
---------------------------acebdf13572468
Content-Disposition: form-data; name="file"; filename="4Byl64P (1).jpg"
Content-Type: image/jpeg
<#INCLUDE *C:\Users\patrick\Pictures\4Byl64P (1).jpg*#>
---------------------------acebdf13572468--