Server is not able to authenticate user if i send NSHTTPCookie iOS9 - python

This may be the basic question but i am unable to investigate the issue. Need your help if anyone experience it.
During creation of NSURLRequest, i am setting handle cookies property to true.
urlRequest.HTTPShouldHandleCookies=true
When login response comes, we are saving cookies; Please have a look at code:
//Stored the cookies in shared place
let allHeaderFileds = httpResponse.allHeaderFields as! [String : String]
let cookies: NSArray? = NSHTTPCookie.cookiesWithResponseHeaderFields(allHeaderFileds, forURL: (response?.URL)!)
if let _ = cookies
{
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookies(cookies! as! [NSHTTPCookie], forURL: (response?.URL)!, mainDocumentURL: nil)
}
When we are making another API call in which we need those cookies, we are also setting it here like following:
let cookieProperties:NSDictionary = [
NSHTTPCookieName:cookie.name!,
NSHTTPCookieValue:cookie.value!,
NSHTTPCookieDomain:cookie.domain!,
NSHTTPCookiePath:cookie.path!
]
let cookie:NSHTTPCookie = NSHTTPCookie(properties: cookieProperties as! [String : AnyObject])!
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(cookie)
When i hit an API call to get data, it returns status code 403 and Message “Authentication credentials were not provided.”
For more details about header, please look into this:
"<NSHTTPURLResponse: 0x7fb5227444a0> { URL: http://172.16.10.249:8001/api/v1/users/profile/ } { status code: 403, headers {\n Allow = \"GET, POST, HEAD, OPTIONS\";\n \"Content-Type\" = \"application/json\";\n Date = \"Thu, 28 Jan 2016 10:22:22 GMT\";\n Server = \"WSGIServer/0.1 Python/2.7.11\";\n Vary = \"Accept, Cookie\";\n \"X-Frame-Options\" = SAMEORIGIN;\n} }"
Please let me know if i am wrong at any point or we need some extra configuration on iOS9. If server need to do some more steps please also mention it. Our server is written in Python.

Related

Not able to fetch discord guild/server/channel members

Tried to get numbers of discord members using discord's API endpoint GET/guilds/{guild.id}/members (see here).
I am using Postman to make a call to it. I set the Authorization header:
Authorization: "Bot ${BOT_TOKEN}"
The response I get is
{ "message": "Missing Access", "code": 50001 }
I also tried with Authorization: DISCORD_CLIENT_ID.
The response is { "message": "401: Unauthorized", "code": 0 }.
Am I missing something? Please help me out with this.
First, you need to make sure you are using the correct guild id and not a channel id. You can enable Developer Mode on Discord through User settings -> Advanced, which allows you to obtain the guild id by right-clicking on a guild (server), and then clicking on Copy ID.
Next, go to your application through Developer Portal, select your application and navigate to the Bot tab on the navigation bar to the left. From there, obtain your bot's authentication token that you need to pass in the headers of your request. On the same tab - since you need to get the list of Guild Members, and since that "endpoint is restricted according to whether the GUILD_MEMBERS Privileged Intent is enabled for your application" - scroll down to the Privileged Gateway Intents section and enable SERVER MEMBERS INTENT.
Below is a working example using the Node.js standard modules. Please note that, as described here, the default limit of maximum number of members to return is 1. Thus, you can adjust the limit in the query parameters, as below, to receive more results per request. The maximum number of results you can get per request is 1000. Therefore, if a guild contains more members than that, you can keep track of the highest user id present in each previous request, and pass it to the after parameter of the next request, as described in the documentation. In this way, you can obtain every member in a guild. Also, make sure you set the properties in options in the proper way, as shown below; otherwise, you might come accross getaddrinfo ENOTFOUND error, as shown here.
Update
If you haven't already, you should add your bot to the server you wish, by generating an invite link for your bot through URL Generator under OAuth2 in your application settings (select bot from scopes). Now, you can access that URL from your browser and add the bot to any of your servers. If you need to, you can share the same invite link with others, so that they can add your bot to their servers.
Example in Node.js
const https = require('https')
const url = require('url');
GUILD_ID = "YOUR_GUILD_ID"
BOT_TOKEN = 'YOUR_BOT_TOKEN'
LIMIT = 10
const requestUrl = url.parse(url.format({
protocol: 'https',
hostname: 'discord.com',
pathname: `/api/guilds/${GUILD_ID}/members`,
query: {
'limit': LIMIT
}
}));
const options = {
hostname: requestUrl.hostname,
path: requestUrl.path,
method: 'GET',
headers: {
'Authorization': `Bot ${BOT_TOKEN}`,
}
}
const req = https.request(options, res => {
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', error => {
console.error(error)
})
req.end()
Example in Python
import requests
import json
GUILD_ID = "YOUR_GUILD_ID"
BOT_TOKEN = 'YOUR_BOT_TOKEN'
LIMIT = 10
headers = {'Authorization' : 'Bot {}'.format(BOT_TOKEN)}
base_URL = 'https://discord.com/api/guilds/{}/members'.format(GUILD_ID)
params = {"limit": LIMIT}
r = requests.get(base_URL, headers=headers, params=params)
print(r.status_code)
print(r.text,'\n')
#print(r.raise_for_status())
for obj in r.json():
print(obj,'\n')

Microsoft Graph API REQUESTS with Python: "Insufficient privileges to complete the operation" error when making simple call

Receiving the following error response when doing a basic Graph API POST using REQUESTS in Python:
{
"error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
"innerError": {
"request-id": "36c01b2f-5c5c-438a-bd10-b3ebbc1a17c9",
"date": "2019-04-05T22:39:37"
}
}
}
Here is my token request and Graph request using REQUESTS in Python:
redirect_uri = "https://smartusys.sharepoint.com"
client_id = 'd259015e-****-4e99-****-aaad67057124'
client_secret = '********'
tennant_id = '15792366-ddf0-****-97cb-****'
scope = 'https://graph.microsoft.com/.default'
####GET A TOKEN
payload = "client_id="+client_id+"&scope="+scope+"&client_secret="+client_secret+"&grant_type=client_credentials"
headers = {'content-type':'application/x-www-form-urlencoded'}
tokenResponse = requests.post('https://login.microsoftonline.com/'+tennant_id+'/oauth2/v2.0/token',headers=headers, data=payload)
json_tokenObject = json.loads(tokenResponse.text)
authToken = json_tokenObject['access_token']
#### Make a call to the graph API
graphResponse = requests.get('https://graph.microsoft.com/v1.0/me/',headers={'Authorization':'Bearer '+authToken})
if tokenResponse.status_code != 200:
print('Error code: ' +graphResponse.status_code)
print(graphResponse.text)
exit()
print('Request successfull: Response: ')
print(graphResponse.text)
print('Press any key to continue...')
x=input()
According to the documentation ( https://learn.microsoft.com/en-us/graph/api/resources/users?view=graph-rest-1.0 ) for this /me call, I need just one of the following permissions:
User.ReadBasic.All
User.Read
User.ReadWrite
User.Read.All
User.ReadWrite.All
Directory.Read.All
Directory.ReadWrite.All
Directory.AccessAsUser.All
and I have all of these on both application and delegated permissions in the azure application manager.
What am I doing wrong here? I feel like it's something small but I just can't figure this out.
I decoded my token using: http://calebb.net/ and I do not see a spot for "AUD" or "role" or "scope" so maybe that is where I am doing it wrong?
I looked everywhere and can't find a resolution, any help would be VERY much appreciated.
Thank you.
This sounds like you forgot to "Grant Permissions" to your application.
See this answer.
I finally figured this out, it had to do with Admin rights that needed to be granted by the Admin for our Office 365.
it was as simple as giving my Office admin the following link and having him approve it:
https://login.microsoftonline.com/{TENNANT ID HERE}/adminconsent?client_id={CLIENT ID HERE}
Instantly worked.

How to correctly generate x-instagram-gis

I have written the following function in Python3.7 to generate x-instagram-gis. According to my research regarding this topic I have gathered that I only need the rhx_gis and variables (id: profile_id, first: int<50, after: end_cursor) to generate the x-instagram-gis.
def generate_x_instagram_gis(rhx_gis, cursor, profile_id):
params = {
"id": profile_id,
"first": 12,
"after": cursor,
}
json_params = json.dumps(params, separators=(',', ':'))
values = "{}:{}".format(rhx_gis, json_params)
return hashlib.md5(values.encode('utf-8')).hexdigest()
Running the following should return: 90bd6b662f328642477076d92d599064
rhx_gis = "7733066781d53e86a089eeb454c5446d"
cursor = "QVFBZWRqS0RnbGMtaXJhQzhlRW01R0I2YngtVXNQOGRTZzdHZEdseGcyVE1MdUxFYmYyY011Zkx6dFZtQUlsYWNvRl9DWnhtalpXZ2daSU5YQnFNTFBGRg=="
profile_id = "6822549659" #https://www.instagram.com/kimimatiasraikkonen/
print(generate_x_instagram_gis(rhx_gis, cursor, profile_id))
But it returns: f5e1e4be6612701d43523d707e36672b
For reference, these are the sources I've looked at:
https://github.com/rarcega/instagram-scraper/issues/205
How to perform unauthenticated Instagram web scraping in response to recent private API changes?
I'm not entirely sure what I'm doing incorrectly, when I run this with my entire program it doesn't work and this is the only part which causes an issue after much testing. Another thing I noted is that the MD5 is different when running on Python3.7 and Python2.7
I have figured it out.
The rhx_gis value is calculated based on the user-agent sent in the headers. The rhx_gis value I was obtaining was retrieved using python requests which sets its own user-agent (python-requests or something similar), whereas the rhx_gis value I was seeing on Postman was created using a different user-agent (set on Postman)
To fix this issue I had to set the same user-agent in python requests as the one set on Postman.
headers = {
'User-Agent' : '' # user-agent here
}
requests.get(url, headers=headers)
It seems that Instagram updated the API again, and a format for query_variable is changed. It looks like as follow:
{
"id":"25025320",
"include_reel":true,
"fetch_mutual":false,
"first":13,
"after":"QVFDZV9udFJKbVk3OGNlOE1LeGx3V1g0aEUyNFNSQTFUenhWOFVkWktTVzdpdUJRSk9EQXY3Ym9QQXFwTWJEci1pYklhSHFGQU1PTnl6QmhZbGpjalplSQ=="
}

Axiom and Flask POST and GET requests, passing arguments

I am learning how web apps work and after successfully creating connection between front and back end I managed to perform get request with axiom:
Route in my Flask
#app.route('/api/random')
def random_number():
k = kokos()
print(k)
response = {'randomNumber': k}
return jsonify(response)
my kokos() function
def kokos():
return (890)
Function that I call to get data from backend:
getRandomFromBackend () {
const path = `http://localhost:5000/api/random`
axios.get(path)
.then(response => {this.randomNumber = response.data.randomNumber})
.catch(error => {
console.log(error)
})
}
Now suppose I have an input field in my App with value that I want to use in the function kokos() to affect the result and what is going to be displayed in my app.. Can someone explain me how to do that?
Is this what POST requests are for and I have to post first and then get? Or can I use still GET and somehow pass "arguments"? Is this even GET and POST are for or am I making it too complicated for myself?
Is this the proper way to do these kind of thing? I just have a lot of code in python already written and want to simply exchange data between server and client.
Thank you, Jakub
You can add second argument
axios.get(path, {
params: {
id: 122
}
})
.then ...
You can pass id like this or anything it will be available in get params at python side like we pass in URL.
python side [Flask] (http://flask.pocoo.org/docs/1.0/quickstart/#accessing-request-data)
To access parameters submitted in the URL (?key=value) you can use the args attribute:
def random_number():
id = request.args.get('id', '')
k = kokos(id)
id will be passed kokos function if no id is provided it will be blank ''
you can read axios docu to make complex requests.
https://github.com/axios/axios
if any doubt please comment.

Blockchain info wallet check payment

i am trying to create bill for payment and send to my customer via telegram bot:
i am using blockchain API V2-https://blockchain.info/api/api receive .my code is:
xpub='***'
keyk='02e57f1***'
url='https://api.blockchain.info/v2/receive?xpub='+str(xpub)+'&callback=https%3A%2F%2Fdoors03.ru&key='+keyk
x=requests.get(url)
r=x.json()
r=r['address']
r -is an adress wich was made.
i am sending it to my costumer(by the way is there any way to send adress with exact sum for pay ) . After i want to check is payment was recieved:
data={ "Content-Type": "text/plain","key":keyk,"addr":r,"callback":"https%3A%2F%2Fdoors03.ru","onNotification":"KEEP", "op":"RECEIVE"}
r = requests.post(url, data=data)
and this is the response - u'{\n "message" : "Internal handlers error"\n}'
what i am doing wrong ? how to check payments ? how to send address with exact sum of btc or ethereum ?
Sorry, i don't have enough reputation to post a comment, so this is
the only option i have. #egorkh have you solved this problem? Maybe
you have received explanation from blockchain.info support? I have
sent them a question about that, but they are answering for too long.
UPDATE: Finally, i have found solution.
In my case, reason of "Internal handlers error" message is in a wrong interpretation of their API.
As they haven't implemented balance_update request in their java-api, i did it on my own and i did it in wrong way.
I have put this parameters:
{"key":keyk,"addr":r,"callback":"https%3A%2F%2Fdoors03.ru","onNotification":"KEEP", "op":"RECEIVE"}
as post parameters, like in other methods they have provided in api. In those methods parameters are URLEncoded like you did with callback link. But...
In this HTML request they must be sent as plain text in json format without any special encoding, like that:
Map<String, String> params = new HashMap<String, String>();
params.put("addr", address);
params.put("callback", callbackUrl);
params.put("key", apiCode);
params.put("onNotification", keepOnNotification? "KEEP" : "DELETE");
params.put("confs", Integer.toString(confirmationCount));
params.put("op", StringUtils.isBlank(operationType) ? "ALL" : operationType);
//parse parameters map to json string(that's optional: you can write it directly as string)
String body = new Gson().toJson(params);
if (requestMethod.equals("POST")) {
byte[] postBytes = body.getBytes("UTF-8");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "text/plain");
conn.setRequestProperty("Content-Length", String.valueOf(postBytes.length));
conn.getOutputStream().write(postBytes);
conn.getOutputStream().close();
}
The main reason of your error may be that you put "Content-Type": "text/plain" in data object (, and maybe encoded callback url) .

Categories

Resources