I read that sending cookies with cURL works, but not for me.
I have a REST endpoint like this:
class LoginResource(restful.Resource):
def get(self):
print(session)
if 'USER_TOKEN' in session:
return 'OK'
return 'not authorized', 401
When I try to access the endpoint, it refuses:
curl -v -b ~/Downloads/cookies.txt -c ~/Downloads/cookies.txt http://127.0.0.1:5000/
* About to connect() to 127.0.0.1 port 5000 (#0)
* Trying 127.0.0.1...
* connected
* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.27.0
> Host: 127.0.0.1:5000
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 401 UNAUTHORIZED
< Content-Type: application/json
< Content-Length: 16
< Server: Werkzeug/0.8.3 Python/2.7.2
< Date: Sun, 14 Apr 2013 04:45:45 GMT
<
* Closing connection #0
"not authorized"%
Where my ~/Downloads/cookies.txt is:
cat ~/Downloads/cookies.txt
USER_TOKEN=in
and the server receives nothing:
127.0.0.1 - - [13/Apr/2013 21:43:52] "GET / HTTP/1.1" 401 -
127.0.0.1 - - [13/Apr/2013 21:45:30] "GET / HTTP/1.1" 401 -
<SecureCookieSession {}>
<SecureCookieSession {}>
127.0.0.1 - - [13/Apr/2013 21:45:45] "GET / HTTP/1.1" 401 -
What is it that I am missing?
This worked for me:
curl -v --cookie "USER_TOKEN=Yes" http://127.0.0.1:5000/
I could see the value in backend using
print(request.cookies)
You can refer to https://curl.haxx.se/docs/http-cookies.html for a complete tutorial of how to work with cookies. You can use
curl -c /path/to/cookiefile http://yourhost/
to write to a cookie file and start engine and to use cookie you can use
curl -b /path/to/cookiefile http://yourhost/
to read cookies from and start the cookie engine, or if it isn't a file it will pass on the given string.
You are using a wrong format in your cookie file. As curl documentation states, it uses an old Netscape cookie file format, which is different from the format used by web browsers. If you need to create a curl cookie file manually, this post should help you. In your example the file should contain following line
127.0.0.1 FALSE / FALSE 0 USER_TOKEN in
having 7 TAB-separated fields meaning domain, tailmatch, path, secure, expires, name, value.
curl -H #<header_file> <host>
Since curl 7.55 headers from file are supported with #<file>
echo 'Cookie: USER_TOKEN=Yes' > /tmp/cookie
curl -H #/tmp/cookie <host>
docs & commit
If you have made that request in your application already, and see it logged in Google Dev Tools, you can use the copy cURL command from the context menu when right-clicking on the request in the network tab. Copy -> Copy as cURL.
It will contain all headers, cookies, etc..
I'm using Debian, and I was unable to use tilde for the path. Originally I was using
curl -c "~/cookie" http://localhost:5000/login -d username=myname password=mypassword
I had to change this to:
curl -c "/tmp/cookie" http://localhost:5000/login -d username=myname password=mypassword
-c creates the cookie, -b uses the cookie
so then I'd use for instance:
curl -b "/tmp/cookie" http://localhost:5000/getData
Another solution using json.
CURL:
curl -c /tmp/cookie -X POST -d '{"chave":"email","valor":"hvescovi#hotmail.com"}' -H "Content-Type:application/json" localhost:5000/set
curl -b "/tmp/cookie" -d '{"chave":"email"}' -X GET -H "Content-Type:application/json" localhost:5000/get
curl -b "/tmp/cookie" -d '{"chave":"email"}' -X GET -H "Content-Type:application/json" localhost:5000/delete
PYTHON CODE:
from flask import Flask, request, session, jsonify
from flask_session import Session
app = Flask(__name__)
app.secret_key = '$#EWFGHJUI*&DEGBHYJU&Y%T#RYJHG%##RU&U'
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
#app.route('/')
def padrao():
return 'backend server-side.'
#app.route('/set', methods=['POST'])
def set():
resposta = jsonify({"resultado": "ok", "detalhes": "ok"})
dados = request.get_json()
try:
if 'chave' not in dados: # não tem o atributo chave?
resposta = jsonify({"resultado": "erro",
"detalhes": "Atributo chave não encontrado"})
else:
session[dados['chave']] = dados['valor']
except Exception as e: # em caso de erro...
resposta = jsonify({"resultado": "erro", "detalhes": str(e)})
resposta.headers.add("Access-Control-Allow-Origin", "*")
return resposta
#app.route('/get')
def get():
try:
dados = request.get_json()
retorno = {'resultado': 'ok'}
retorno.update({'detalhes': session[dados['chave']]})
resposta = jsonify(retorno)
except Exception as e:
resposta = jsonify({"resultado": "erro", "detalhes": str(e)})
resposta.headers.add("Access-Control-Allow-Origin", "*")
return resposta
#app.route('/delete')
def delete():
try:
dados = request.get_json()
session.pop(dados['chave'], default=None)
resposta = jsonify({"resultado": "ok", "detalhes": "ok"})
except Exception as e: # em caso de erro...
resposta = jsonify({"resultado": "erro", "detalhes": str(e)})
resposta.headers.add("Access-Control-Allow-Origin", "*")
return resposta
app.run(debug=True)
Here is an example for the correct way to send cookies. -H 'cookie: key1=val2; key2=val2;'
cURL offers a convenience of --cookie as well. Run man curl or tldr curl
This was copied from Chrome > inspect >network > copy as cURL.
curl 'https://www.example.com/api/app/job-status/' \
-H 'authority: www.example.com' \
-H 'sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.111.111 Safari/111.36' \
-H 'content-type: application/json' \
-H 'accept: */*' \
-H 'origin: https://www.example.com' \
-H 'sec-fetch-site: same-origin' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-dest: empty' \
-H 'referer: https://www.example.com/app/jobs/11111111/' \
-H 'accept-language: en-US,en;q=0.9' \
-H 'cookie: menuOpen_v3=true; imageSize=medium;' \
--data-raw '{"jobIds":["1111111111111"]}' \
--compressed
I am using GitBash on Windows and nothing I found worked for me.
So I settled with saving my cookie to a file named .session and used cat to read from it like so:
curl -b $(cat .session) http://httpbin.org/cookies
And if you are curious my cookie looks like this:
session=abc123
Related
settings.py
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
views.py
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="接口文档",
default_version='v1',
description="使用youtube-dl 下载视频",
contact=openapi.Contact(email="wh970305#163.com"),
),
public=True,
)
then the API return Authentication credentials were not provided.
because the token is wrong
curl -X GET "http://localhost:8000/api/auth/info" -H "accept: application/json" -H "authorization: Basic YWRtaW46MTIzNDU2" -H "X-CSRFToken: TQ31NEGiMUJVUvqJKVKyua1hWgmHP614t0skwPqxQT0JvUR8PMqzXgIqAKzcgEhW"
Try this way: Authorization: Bearer JWT_ACCESS_TOKEN
I'm issuing the following request:
curl --http2 -X "POST" "http://localhost:8088/query-stream"
-H "Content-Type: application/vnd.ksql.v1+json; charset=utf-8"
-d $'{
"sql": "SELECT * FROM USERS EMIT CHANGES;",
"streamsProperties": {
"ksql.streams.auto.offset.reset": "earliest"
}
}
The result I'm getting is:
{"queryId":"cdfb3ccc-0ab5-4186-a249-b279bfc09587","columnNames":["USERID","NAME"],"columnTypes":["STRING","STRING"]}
["1","Max"]
["2","Alex"]
["13","Andrew"]
...
Is there a way I could get the data in json format?
{"userid":"1","name":"Max"}
{"userid":"2","name":"Alex"}
{"userid":"13","name":"Andrew"}
It is easier to deserialize this data into POCO objects if they are in json than to parse the 'row' format.
Per the docs you can set the Accept header. It defaults to application/vnd.ksqlapi.delimited.v1 but can also be set to application/json:
curl --show-error --silent \
-H "application/vnd.ksqlapi.delimited.v1" \
--http2 'http://localhost:8088/query-stream' \
--data-raw '{"sql":"SELECT * FROM CUSTOMERS WHERE ID=42;"}'
{"queryId":null,"columnNames":["ID","FIRST_NAME","LAST_NAME","EMAIL","GENDER","COMMENTS"],"columnTypes":["INTEGER","STRING","STRING","STRING","STRING","STRING"]}
[42,"Rick","Astley","r.astley#example.com","Male",""]
curl --show-error --silent \
-H "Accept:application/json" \
--http2 'http://localhost:8088/query-stream' \
--data-raw '{"sql":"SELECT * FROM CUSTOMERS WHERE ID=42;"}'
[{"queryId":null,"columnNames":["ID","FIRST_NAME","LAST_NAME","EMAIL","GENDER","COMMENTS"],"columnTypes":["INTEGER","STRING","STRING","STRING","STRING","STRING"]},[42,"Rick","Astley","r.astley#example.com","Male",""]]
I am sending a curl command to a server, but get an error message which I do not understand.
The request I need to send to the server is
body=$(cat << EOF
{
"order": {
"units": "100",
"instrument": "EUR_USD",
"timeInForce": "FOK",
"type": "MARKET",
"positionFill": "DEFAULT"
}
}
EOF
)
curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TOKEN>" \
-d "$body" \
"https://api-fxtrade.oanda.com/v3/accounts/<ACCOUNT>/orders"
What I do is that I translate this into a curl command like :
curlcmd = 'curl -s \ -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer " \ -d "{"order": {"units": "100", "instrument": "EUR_USD", "timeInForce": "FOK", "type": "MARKET", "positionFill": "DEFAULT" }}" \ "https://api-fxpractice.oanda.com/v3/accounts/AccountID/orders"'
I send the command via resp = system (curlcmd) via Matlab to the server. What I get as an error message is :
errorMessage: 'Invalid JSON, ParseErrorCode: 4, Message: Missing a name for object member.'
Any idea what this means and how I can solve this ? I am using Matlab on Windows 10, so curl is part of Windows 10.
Response should be a placed order and response data of the trade.
The JSON doesn't seem to be properly quoted.
Try this:
curl -s -X POST -H "Content-Type: application/json" -H "Authorization: Bearer " -d "{\"order\": {\"units\": \"100\", \"instrument\": \"EUR_USD\", \"timeInForce\": \"FOK\", \"type\": \"MARKET\", \"positionFill\": \"DEFAULT\" }}" "https://api-fxpractice.oanda.com/v3/accounts/AccountID/orders"
Test with Proxy
With the appropriate escape of the JSON quotes, as shown in the above CURL command line, the JSON looks correct when viewed in an HTTPS proxy:
I am trying to access a remote service using "F# Data Http Utilities" but without success:
let account token = Http.RequestString("https://api.example.com/v1",
httpMethod = "POST",
headers = ["Accept", "application/json";
"Content-Type", "application/json";
"X-Application", "JRQ";
"X-Authentication", "MOl5C9ZZ";],
body = TextRequest """ {"jsonrpc": "2.0", "method": "getAccount"} """)
even though both the curl and PowerShell equivalents work correctly:
curl -i -X POST \
-H "Accept:application/json" \
-H "Content-Type:application/json" \
-H "X-Application:JRQ" \
-H "X-Authentication:MOl5C9ZZ" \
-d '{"jsonrpc": "2.0", "method": "getAccount"}' \
'https://api.example.com/v1'
What am I missing?
It seems that there is no error in the original F# code. Setting the following property:
System.Net.ServicePointManager.Expect100Continue <- false;
resolved the problem!
I am trying to assign standard gateway role to a gateway device as per docs available
https://docs.internetofthings.ibmcloud.com/apis/swagger/v0002-beta/security-gateway-beta.html#!/Limited_Gateway/put_authorization_devices_deviceId_roles
But I keep on getting 403 Forbidden error. I am using app credentials (api key and token) which has "Operations application" role and hence privileges to assign roles.
Here are few scripts which are run, where I have replaced org, type, id and token with dummy values
curl -X PUT \
https://dummyorg.internetofthings.ibmcloud.com:443/api/v0002/authorization/devices/g%3Adummyorg%3Adummytype%3Adummyid/roles \
-H 'authorization: Basic dummyauth' \
-H 'content-type: application/json' \
-d '{
"roles": [
{
"roleId": "PD_STANDARD_GW_DEVICE",
"roleStatus": 1
}
]
}'
Response
HTTP 403 forbidden
When I try to get the role of device, it works fine
curl -X GET \
https://dummyorg.internetofthings.ibmcloud.com:443/api/v0002/authorization/devices/g%3Adummyorg%3Adummytype%3Adummyid/roles \
-H 'authorization: Basic dummyauth' \
Response
{
"results": [
{
"roleId": "PD_PRIVILEGED_GW_DEVICE",
"roleStatus": 1
}
],
"rolesToGroups": {}
}
Note the url - you have to use the 'g' and you have to encode it. You need to include a Basic Authorisation header which has your API keys (mine are Standard Application):
PUT /api/v0002/authorization/devices/g%3AOrgID%3Agatewaytype%3AmyGateway/roles HTTP/1.1
Host: OrgID.internetofthings.ibmcloud.com
Authorization: Basic removed
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: removed
{
"roles": [
{
"roleId": "PD_STANDARD_GW_DEVICE",
"roleStatus": 1
}
],
"rolesToGroups": {}
}