Python - how to authenticate the server and the api? - python

I am trying to send an API request to a server that needs http authentication.
The (Wordpress server) is set to authenticate the API using basic authentication.
First I am setting the session using the code
with requests.sessions.Session() as session:
session.auth = ('my_user', 'my_password')
session.get(url)
I get 200 as expected.
Then I send the API request
credentials = "user:password"
token = base64.b64encode(credentials.encode())
header = {"Authorization": "Basic " + token.decode('utf-8')}
response = requests.get(url=url, headers=header)
But I get error 401 in the response.
How can I do it differently to make it work?

i have some sample of mine, i hope it'll help you:
header = {....}
data = {...}
response= requests.post(url=url, data=data,headers=header,auth=(user,password))

as far as I know, wordpress does not even accept Authentication user/password by default.
you can only login through cookies (source)
but there is a way to authenticate rest api using user/password and that is plugins. I suggest Wordpress REST API Authentication
then usage would be so easy like :
import requests
headers = {
'Authorization': 'Basic base64encoded <username:password>',
'Content-Type': 'application/x-www-form-urlencoded',
}
data = 'title=sample post&status=publish'
response = requests.post('http://example.com/wp-json/wp/v2/posts', headers=headers, data=data)

Taking from the two answers (thanks!), here is the answer that is a merge of the two.
The API authentication is sent in the header (and an API authentication plugin is needed in WP).
credentials = "user:password"
token = base64.b64encode(credentials.encode())
header = {"Authorization": "Basic " + token.decode('utf-8')}
The session authentication is sent in the auth parameter of the request
response = requests.get(url=url, headers=header, auth=('my_user', 'my_password'))

Related

How get bearer token with requests from python

I'm trying to replicate a login to a page with python and the requests module but I need a token bearer.
This site doesn't require a login password connection but just an event code (wooclap.com)
I cannot find when the token is recovered by looking at header and json responses.
If you can help me
Thanks
once you put in a event code check the network tab on you're chrome console there should be a request wich returns the token. either in the reponse header or the json,
I'd recommend finding it using DevTools in your browser (F12).
In network you can see the login request mainly under headers and response. I've used this to implemented it below in python for you.
import requests
# Set the URL of the login page
url = "https://app.wooclap.com/api/auth/local/login"
# Set the login credentials
data = {"username": "< !!enter username here!! >", "password": "< !!enter password here!! >"}
# Send the login request and store the response
response = requests.post(url, data=data)
# Get the JSON response body
json_response = response.json()
# Get the AWT token from the JSON response
awt_token = json_response.get("token")
# Set the URL of the resource you want to access
url = "https://app.wooclap.com/public/events"
# Set the authorization header of your request, using the Bearer scheme
headers = {"Authorization": f"Bearer {awt_token}"}
# Send the request and store the response
response = requests.get(url, headers=headers)
print(response.text)
To send a GET request with a Bearer Token authorization header using Python, you need to make an HTTP GET request and provide your Bearer Token with the Authorization: Bearer {token} HTTP header

POST build to TeamCity queue

I am trying to use the TeamCity REST API to add a build to the queue but am running into some difficulty with authorization.
I have the url to our teamcity server defined, and have generated an authorization token through the admin page
TEAMCITY_URL = 'http://teamcity.somedomain.com'
BEARER_TOKEN = 'SOMELONGTOKEN'
With this URL and token I can successfully make GET requests
import json
import requests
session = requests.Session()
session.headers.update({
'Accept': 'application/json',
'Authorization': f'Bearer {BEARER_TOKEN}',
})
response = session.get(f'{TEAMCITY_URL}/app/rest/projects/example/buildTypes')
assert(response.status_code == requests.codes.ok) # this succeeds, can parse response fine later
but then if I try to POST a build to the queue I get a 403
payload = {
'branchName': 'master',
'buildType': {
'id': buildID # assume this was already defined
}
}
response = session.post(f'{TEAMCITY_URL}/app/rest/buildQueue', json=payload)
assert(response.status_code == requests.codes.ok) # fails with 403
the latter response.text is
'403 Forbidden: Responding with 403 status code due to failed CSRF check: authenticated POST request is made, but neither tc-csrf-token parameter nor X-TC-CSRF-Token header are provided.. For a temporary workaround, you can set internal property teamcity.csrf.paranoid=false and provide valid Origin={teamcity_url} header with your request\n'
How can I correctly use this bearer token to perform a POST request?
The fix for this was I needed to first make a GET request for a CSRF token. I could then use this token to update the session headers with a 'X-TC-CSRF-Token' as follows
response = session.get(f'{TEAMCITY_URL}/authenticationTest.html?csrf')
assert(response.status_code == requests.codes.ok)
csrf_token = response.text
session.headers.update({
'X-TC-CSRF-Token': csrf_token
})
then the subsequent POST would succeed. More details in official docs.

How to return a bearer JWT token FROM Flask?

How to form a response from Flask python server which would contain the bearer token in the response. More precisely, I am looking to somehow securely propagate the JWT token from Flask python server back to the client (angular page). I can just return it in form of the querystring in GET redirect. What are other possibilities in terms of returning the JWT access token back to the client? I tried setting the response form python, and to set the jwt token in Authorization field, but nothing worked. This is what I tried:
1.
r = Response(headers={
"Authorization": "bearer jwtcntent",
"Access-Control-Allow-Origin": "*",
},
is_redirect=True,
url="https://localhost:5000/callback",
)
return r
r = redirect("http://localhost:5000/callback")
r.headers = {"authorization": "bearer jwtcntent"}
return r
r = Response(headers={
"Authorization": "Bearer jwtcntent",
"Access-Control-Allow-Origin": "*",
},
allow_redirects=True,
url="https://localhost:5000/callback",
)
return r
Any recommendations?
You can store it in an httponly cookie, but you need to make sure to handle CSRF attacks if you do so. Flask-JWT-Extended has built in support for this which you might find useful, either as a solution or as a reference for whatever you end up doing:
https://flask-jwt-extended.readthedocs.io/en/stable/token_locations/#cookies
You can also just send the token back as part of the JSON body and then storing it in local/session storage, which is probably the most common pattern.
Are you able to implement a regular OAuth flow in your Authorization Server? OAuth flows are standardized and use secure ways of returning an access token to the client.
I don't recommend using the Authorization header for returning responses. This header is a request header, it has no meaning in a response. If you really need to do it through the header you can add Access-Control-Expose-Headers header to let your client read the Authorization header from a response.

Where do I add my authorization token when making a request to the YouTube v3 Data API?

I'm currently using the Python Requests module to add videos to a playlist created by me. On the docs for playlistItems.insert, it says authorization is required with one of three possible scopes. I have created an OAUTH2.0 credential token in my project's credential panel and set the scope correctly. Currently I'm trying to pass the credential as follows:
payload = {
'access_token': [My Client ID],
'part': 'snippet'}
new_vid = requests.post(f'{base_url}playlistItems', params=payload)
When executing the code, I get the following error message:
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project."
Am I passing the authorization token in the correct place, or should I be passing it somewhere else in the POST request?
You can pass the Authorization token as a header parameter. Check the example below:
import requests
headers = {
'Authorization': 'Bearer [YOUR_ACCESS_TOKEN]',
'Accept': 'application/json',
'Content-Type': 'application/json',
}
params = (
('key', '[YOUR_API_KEY]'),
('part','snippet')
)
response = requests.post('https://youtube.googleapis.com/youtube/v3/playlistItems', headers=headers, params=params)

How to send authentication credentials in app.post for Flask unit testing of API views

I have written a Flask application. In that, I am using basic auth to restrict certain POST API views.
From Python requests, I can access those views as -
print post(url, json=data, auth=('username', 'password'))
And from curl,
curl -a username:password -d "data" url
How to do the same in app.post ? I tried auth, authorization etc as parameters to post but they were invalid.
response = self.app.post(
url,
data=data,
headers={
'content-type': 'application/json'
},
follow_redirects=True
)
Basic authorization credentials are stored in header as follows -
"Authorization": "Basic username:password"
However the username:password part is base64 encoded. So one can use the base64 module to do the same.
import base64
headers={
'content-type': 'application/json',
'Authorization': 'Basic %s' % base64.b64encode('username:password')
}
In the above case, the Authorization will be set to Basic dXNlcm5hbWU6cGFzc3dvcmQ=
This will allow you to use basic authorization from Flask testing framework.
Cheers !!
I find the above method right for sending the post request in unit testing.
But for doing so you should have to keep in mind that you should have to disable the CSRF protection in the testing configuration.
class TestingConfig(Config):
WTF_CSRF_ENABLED = False
and best of luck for GSOC 16.

Categories

Resources