sending a GET request with payload in Python - python

I'd like to call the Facebook graph API to query some information about an object. The GET method is required. However, for security purposes, I'd like to hide the access token in a payload. I tested in Graph API Explorer. It worked. But I cannot do it using Python code.
import requests
r = requests.get(url, data={'access_token' : '0123456789ABCDEF',})
r.text
The response is
{"error":{"message":"An access token is required to request this resource.","type":"OAuthException","code":104,"fbtrace_id":"AQshJ5NFFYMaED92Azgo0AL"}}
I changed data= to json= and it does not work.

Modify your URL to URL+parameter
Eg:
https://graph.facebook.com/me?access_token=ACCESS_TOKEN
Different way:
payload = {'access_token': 'ACCESS_TOKEN'}
r = requests.get('https://graph.facebook.com/me', params=payload)
If you want to avoid insecureness of exposing access token, You can use appsecret_proof along with the parameters. So, spamming becomes impossible.
This simple encryption technique avoids the usage of access token without proof.
An access token can also be stolen by malicious software on a person's
computer or a man in the middle attack
You can prevent this by adding the appsecret_proof parameter to every
API call from a server and enabling the setting to require proof on
all calls
.

Related

Steam API - UpdateAuthSessionWithMobileConfirmation

There was a question about an undocumented method in the steam api, which serves to confirm authorization in the client (https://steamapi.xpaw.me/#IAuthenticationService/UpdateAuthSessionWithMobileConfirmation). With the help of Charles proxy, I saw a discrepancy with the documentation, instead of post parameters in the request, access_token is passed in the get parameter. When you try to retry the request, a 500 error is returned. The question is, how to implement the execution of this API method and what is needed for this? Is it possible to use another undocumented method to confirm authorization - UpdateAuthSessionWithSteamGuardCode and where can I get the parameters for its implementation? if anyone has an example of the implementation of these methods in python?
I tried to make a test request in python, but in response I received a 401 error, although according to the documentation I passed the necessary parameter
import requests
url = "https://api.steampowered.com/IAuthenticationService/UpdateAuthSessionWithMobileConfirmation/v1/"
data = {
'key': 'my steam web api key from [https://steamcommunity.com/dev/apikey]'
}
req = requests.post(url,data)
print(req.status_code) # 401
maybe there are convenient libraries for python where these methods are implemented?

Missing secret gists in GitHub's API

According to the documentation, I can either send the request with authorization (token) in order to get all of my gists, or anonymously and I will get public popular gists.
My Python code is:
url = "https://api.github.com/gists"
with Get(
url,
headers={"Accept": accept},
params={"since": since, "per_page": per_page, "page": page},
auth=("token", token)
) as response:
return response
When token is set to None, I get all public gists (not mine) and when token is set to my OAuth token, I get all of my gists.
However, the issue is that it only gives me my non-secret gists instead of secret and public together.
Initially I was thinking that my token was wrong and therefore I was not getting the secret gists, but turns out that the token is correct (for sure, I can even post new gists) and also has permissions to read/write gists, and that is why it is weird.
The issue is also not related to either params or headers, tested.
Additional Information:
Get is a class which implements a context-manager and sends a get request [link].
After a long research I found out that GitHub's OAuth token from Developer Settings is not enough to perform this action and I need to create a GitHub App in order to extend GitHub.
I used this tool:
https://github.com/defunkt/gist
in order to ask GitHub for such a particular token (which is being used in the GitHub App), and then I started using it, and it worked!
With the new fine grained personal access tokens this can now be done without a GitHub App:
You need to give read-write access to Gists under Account Permissions:

How to get access token of telegram's telegraph account?

I would like to create and edit pages on Telegram's telegraph.ph website through telegraph API.
https://telegra.ph/api#createPage
To do so, I need to know the access token of the telegraph account. I've been searching high and low using Google how to do it but still can't find any answer.
I am using telegraph python library.
https://github.com/python273/telegraph
I am using python 3.7
There is no available endpoints to obtain actual access_token on Telegraph API.
But... If you really need to obtain exactly yours Telegraph access_token,
You can get it by accessing devtools in browser, while authenticated in Telegra.ph via their bot.
It passed as a cookie tph_token and being sent to check authorization at https://edit.telegra.ph/check endpoint.
Look at Network tab in your devtools, switch to XHR requests filter, then choose check request (example)
At the bottom of devtools window, you will see another appeared window, with Headers tab selected.
Go to Cookies and then you will see your token, that you can use as an access_token
It's not an endpoint, by I'm sure, that you can use that instruction to automate obtaining that token, by capturing and parsing some requests, or passing auth url from Telegraph bot expicitly to your python project.
I don't know how. Somehow. But sure, that if you want, my answer will help you to create obtaining algorithm
The API endpoint you're looking for is createAccount. Invoking this endpoint returns an object containing an accesstoken.
From the docs:
On success, returns an Account object with the regular fields and an additional access_token field.
Having said that, the library you've mentioned makes it much easier to work with the api. You don't even to know the access_token explicitly. You only need to call .create_account() and the library will manage the token internally (see here and here to know how).
Here is a sample code on how to use the lib to create an account and utilize it:
from telegraph import Telegraph
telegraph = Telegraph()
acc = telegraph.create_account(short_name='1337')
print(acc)
response = telegraph.create_page(
'Hey',
html_content='<p>Hello, world!</p>',
)
I will answer my own question.
To add on to Tibebes. M's helpful answer, there seems to be no way to get the access token of an existing Telegraph account. So, the only way is to create the account first, then note down the returned access token. Reuse this access token in future. Otherwise, one will have to create a new account whenever a new Telegraph message is posted. I don't know why Telegraph is designed this way because it will result in many stale accounts but that's just the way it is.

Google service account access token request: "Required parameter is missing: grant_type"

UPDATE: Solved. I was indeed making a basic mistake, among other things. My usage of the session.headers.update function was incorrect; instead of session.headers.update = {foo:bar}, I needed to be doing session.headers.update({foo:bar}). Additionally, I changed the following section of code:
From this:
payload = urllib.parse.urlencode({
"grant_type":"urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": str(token)
})
To this:
payload = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=" + token.decode("utf-8")
The code now works as intended.
Original question below
I've seen several hits on SO and Google about this problem; none of them have helped, although I've certainly made sure to double-check my code to make sure I'm not guilty of the same problems they detail. The problems people tend to have involve passing the POST data as parameters or POSTing to the wrong URL, which I'm not doing, as far as I can tell. Additionally, most of the hits I've found involve 3-legged OAuth2 involving users; I've found comparatively few hits pertaining to service accounts and JWTs, which differ enough from the user flow that I'm concerned about how relevant they are to my problem.
I'm trying to get an access token from the Google Authentication server for a service account. I've generated my JWT and now want to POST to the server to receive back my access token. I've set the headers according to the documentation described here, under "Making the access token request," and as far as I can tell, my request is up to spec, but Google responds back with a 400 response, and the following JSON:
{'error': 'invalid_request', 'error_description': 'Required parameter is missing: grant_type'}
Here's the code causing the problem:
# Returns the session, now with the Host and Authorization headers set.
def gAuthenticate(session):
token = createJWT()
session.headers.update = {
"Host": "www.googleapis.com",
"Content-Type": "application/x-www-form-urlencoded"
}
payload = urllib.parse.urlencode({
"grant_type":"urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": str(token)
})
response = session.post("https://www.googleapis.com/oauth2/v4/token", data = payload)
session.headers.update = {"Authorization": "Bearer " + response.json()["access_token"]}
return session
I'm having a lot of strange issues with this code. First of all, if I don't urllib.parse.urlencode my dictionary (i.e. simply payload = {dictionary}), I get only a Bad Request / 'invalid_request' error, which I assume from the less specific error message means that this is less acceptable than what I'm currently doing. Why do I have to do this? Isn't Requests supposed to encode my data for me? I've never had this problem when POSTing with Requests before.
Second, examining the prepared request before it's sent reveals that my headers aren't being correctly set, despite the header update. Neither of the headers I've added to the request are being transmitted.
I've examined the request body and it looks to be identical (except of course the content of the JWT) to the one that Google provides as an example in the documentation.
All of this leads me to believe that I'm making a very basic error somewhere, but I haven't had any success finding it. What am I doing wrong here? Links to any helpful documentation would be extremely appreciated; thanks for your time and attention.
Try "grant_type": "authorization_code". And add grant type as header.
Also, check this link - Accessing Google oAuth giving invalid grant_type (Bad request)

How to create a Wikipedia bot to add a new section to a talk page?

We need to implement a bot which posts new sections on Wikipedia Talk pages.
As a matter of efficiency, we prefer to use python HTTP POST requests using MediaWiki API rather than available MediaWiki libraries.
We have not requested for an approval for the bot, and we are just trying to implement a trial version to test the bot on our own Talk pages.
For this purpose, I went through the following steps:
1- As discussed at https://en.wikipedia.org/wiki/Wikipedia:Creating_a_bot:
Create an account for your bot. Click here when logged in to create the account, linking it to yours. (If you do not create the bot account while logged in, it is likely to be blocked as a possible sockpuppet or unauthorised bot until you verify ownership)
Create a user page for your bot. Your bot's edits must not be made under your own account. Your bot will need its own account with its own username and password.
So, I logged in to my own Wikipedia account, and created a new account (for the bot).
2- As discussed at "API:Login" page: (Sorry, because of having less than 10 reputation, I am not able to add more than 2 links)
Logging in through the API requires two requests. For the first request, I wrote the following code in python:
def logInRequestToWikipedia():
# Add required parameters to the request.
request = { 'action' : 'login' }
request['lgname'] = 'BotName'
request['lgpassword'] = '*************'
url = 'https://en.wikipedia.org/w/api.php'
headers = { 'content-type' : 'application/x-www-form-urlencoded' }
r = requests.post(url, data = json.dumps(request), headers=headers)
The response starts with an error as follows:
<error code="help" info="" xml:space="preserve">
And continues with the API documentation.
3- As discussed at "API:Edit_-_Create%26Edit_pages" page:
Note: In this example, all parameters are passed in a GET request just for the sake of simplicity. However, action=edit requires POST requests; GET requests will cause an error. Do not forget to set the Content-Type header of your request to application/x-www-form-urlencoded. The token that you received is terminated with +\, this needs to be urlencoded (so it will end with %2B%5C) before it is passed back.
I added each of the following parameters separately and both together in the request data and tried all three cases, but it returns the same response.
request['lgtoken'] = '%2B%5C'
request['Content-Type'] = 'application/x-www-form-urlencoded'
4- Also I tried each of the followings in my request data, but it returns the same response:
request['format'] = 'json'
request['format'] = 'xml'
5- Moreover I found the following instruction at "User-Agent_policy" page:
User agents (browsers or scripts) that do not send a User-Agent header may now encounter an error message like this:
Scripts should use an informative User-Agent string with contact information, or they may be IP-blocked without notice.
User agents that send a User-Agent header that is blacklisted (for example, any User-Agent string that begins with "lwp", whether it is informative or not) may encounter a less helpful error message (lie) like this:
Our servers are currently experiencing a technical problem. This is probably temporary and should be fixed soon. Please try again in a few minutes.
This change is most likely to affect scripts (bots) accessing Wikimedia websites such as Wikipedia automatically, via api.php or otherwise, and command line programs.[3] If you run a bot, please send a User-Agent header identifying the bot and supplying some way of contacting you, e.g.:
User-Agent: MyCoolTool/1.1 (http://example.com/MyCoolTool/; MyCoolTool#example.com) BasedOnSuperLib/1.4
Do not copy a browser's user agent for your bot, as bot-like behavior with a browser's user agent will be assumed malicious.[4] For more information, please refer to the MediaWiki API Documentation
That's why I also tried my script with the following parameter, but the error response did not change:
request['User-Agent'] = "MyCoolTool/1.1 (http://example.com/MyCoolTool/; MyCoolTool#example.com) BasedOnSuperLib/1.4"
Do you think the problem can be related to the fact that we have not requested for an approval for the bot yet? Because we are just trying to implement a trial version to test the bot on our own Talk pages, and apply for the approval after making sure everything will work.
I'm pretty sure the problem is this line:
request['lgtoken'] = '%2B%5C'
The Login API you linked to doesn't include an lgtoken on the initial login attempt; it's only sent on the second ("Confirm token") step, using the token value from the NeedToken response.
And +\ doesn't look like a valid token.
So it's not surprising that you're getting an error.
Meanwhile, when I test this with my Wikipedia account, I get an error if I include that line, and success if I don't, which validates my suspicion that this is the problem.

Categories

Resources