I am just getting started with Python3 and asynchronous programming with aiohttp. The problem I am running into is that I can make a post using the request lib and authenticate to the slack api, but when I try to use aiohttp, I cannot authenticate. I have tried all of the permutations of examples I can find on aiohttp, but have not had any luck
requests:
token = {"token": "abc123"}
requests.post('https://slack.com/api/auth.test', data=token)
{'ok': True,
'team': 'foo',
'team_id': 'T5YYYYYY',
'url': 'https://foo-chat.slack.com/',
'user': 'foobar',
'user_id': 'XXXXXXX'}
aiohttp:
async def main():
async with aiohttp.ClientSession() as session:
token = {"token": "abc123"}
async with session.post('http://slack.com/api/auth.test', data=token) as resp:
print(resp.status)
print(await resp.json())
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
200
{'ok': False, 'error': 'not_authed'}
Related
I am implementing the Microsoft Auth code flow but I am stuck with this error.
Based on this code example, here is how I am initializing the client:
const config = {
auth: {
clientId: process.env.MICROSOFT_CLIENT_ID,
authority: process.env.MICROSOFT_AUTHORITY,
clientSecret: process.env.MICROSOFT_CLIENT_SECRET,
},
};
const cca = new msal.ConfidentialClientApplication(config);
And later I want to create an authentication URL to redirect the user to:
const authCodeUrlParameters = {
scopes: ["user.read"],
redirectUri: "http://localhost:8080/oauth/microsoft",
state: 'state_here',
};
cca
.getAuthCodeUrl(authCodeUrlParameters)
.then((authCodeUrl) => {
return authCodeUrl;
})
.catch((error) => console.log(JSON.stringify(error)));
But I am getting this error: {"errorCode":"empty_url_error","errorMessage":"URL was empty or null.","subError":"","name":"ClientConfigurationError"}
Based on the docs about errors, it looks like it's thrown before requests are made when the given user config parameters are malformed or missing.
Anybody can spot where the configs are malformed?
The error is because of the missing configuration requirements in the application.
And most importantly , check the authorization request url for missing parameters like state and nonce and the redirect url.
Here request URL may require state and nonce parameters form cache as part of authCodeUrlParameters to construct the URL.
In authCodeUrlParameters see which of them is missed as they may lead to url to null.
You try to give your domain in knownAuthority
Ex:
auth: {
clientId: 'xxxx-xx-xx-xx-xxxxx',
authority: '<give authority>',
knownAuthorities: ['<domain here>']
redirectUri: 'https://localhost:8080'
},
cache: {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: false,
secureCookies: false
},
Please make sure the redirect url is in correct format:
See Redirect URI (reply URL) restrictions - Microsoft Entra | Microsoft Learn
After setting the correct url, I could get proper response
From my readings, it seems like Twitter's OAuth V2 is not giving the email of the user when you authorize an app, which is clearly hard then to know which user is linked to who.
Then I've seen that the Oauth V1 might help to have back the email of the user, but in order to have something working, you need to make 3 requests.
So maybe someone can help me here and let me know how can I let a user authorize my app like with oAuth V2?
// route.js
import axios from 'axios';
import {v1 as uuidv1} from 'uuid';
import crypto from 'crypto';
import qs from 'qs';
import oauthSignature from 'oauth-signature';
// routes.js - /auth/twitter
// this should return a oauth_token / oauth_token_secret / oauth_callback_confirmed
// https://developer.twitter.com/en/docs/authentication/oauth-1-0a/obtaining-user-access-tokens
const oauth_nonce = uuidv1();
const oauth_timestamp = Math.floor(Date.now() / 1000);
const oauth_signature_rfc_b64 = oauthSignature.generate('POST', process.env.TWITTER_AUTH_TOKEN_URL, {
include_entities: true,
oauth_consumer_key: process.env.TWITTER_CONSUMER_API_KEY,
oauth_nonce,
oauth_signature_method: 'HMAC-SHA1',
oauth_timestamp,
oauth_token: process.env.TWITTER_ACCESS_TOKEN,
oauth_version: "1.0",
}, process.env.TWITTER_CONSUMER_API_KEY_SECRET, process.env.TWITTER_ACCESS_TOKEN_SECRET)
const response = await axios.post(
process.env.TWITTER_AUTH_TOKEN_URL, '',
{headers: {
oauth_consumer_key: process.env.TWITTER_CONSUMER_API_KEY,
oauth_token: process.env.TWITTER_ACCESS_TOKEN,
oauth_signature_method: 'HMAC-SHA1',
oauth_version: "1.0",
oauth_callback: process.env.TWITTER_REDIRECT_URL,
oauth_nonce,
oauth_timestamp,
oauth_signature: oauth_signature_rfc_b64
}},
);
I've switched almost every parameters, API_KEY, SECRET, headers, params etc etc but nothing is working and i get an error code 32 from the twitter response, but nothing else.
If someone has already used node and axios to craft this king of request or know how to use OAuth 1.0 to do the same as OAuth 2.0 could you please help me?
At the moment, the v2 API does not provide access to a user's email address (although this is a known request, and may be added in the future). Since you are using JavaScript, you can use any of the existing JavaScript client libraries for the API that will wrap up the OAuth process for you.
We are building a react-native chat app. We are implementing a back end authentication solution on google Firebase. The creation of a new user in Firebase Auth triggers a cloud function which should create a new SendBird user with an access token. The access token will be stored in Cloud Firestore, ready for retrieval the next time the user logs in.
We are having trouble implementing the POST request that creates the new user via the platform API. We are using the Request library for node.js. We are able to reach the API endpoint, but the following object is returned: { message: 'SendBird API Endpoint.', error: true }. There is no indication of what the error may be.
This happens when sending the request to the base url. When we send the request to /users or /v3/users, we receive a 403 error.
Any indication as to what may be causing this problem would be greatly appreciated.
Below is the cloud function index.js code
const functions = require('firebase-functions');
const admin = require("firebase-admin");
const request = require('request');
admin.initializeApp();
exports.handleNewUser = functions.auth.user().onCreate((user) => {
var newUserRequestBody = {
"user_id": user.email,
"nickname": user.email,
"profile_url": "",
"issue_access_token": true,
}
request.post({
headers: {
'Content-Type': 'application/json, charset=utf8',
'Api-Token': // API Token
},
url: 'https://api-{application_id}.sendbird.com',
form: newUserRequestBody
}, function(error, response, body){
if (!error && response.statusCode === 200) {
const info = JSON.parse(body);
console.log("request successful");
console.log(response.statusCode);
console.log(info);
}
else{
console.log("request unsuccessful");
console.log(response.statusCode);
console.log(error);
}
});
return null;
});
Did you try with full path of end point to url: (including /v3/users)?
Or you may need to use "baseUrl" like below?
https://github.com/request/request#requestoptions-callback
Also, you need to make sure that you correctly used {application_id} value and {API Token} value.
You can double check this from your dashboard of SendBird.
http://dashboard.sendbird.com > Log in with your ID > select your APP.
There is a section named "App credentials" in "Overview" menu.
You can double check your API-request URL and API-Token value from there.
I've set up a lambda function and created some GET and POST methods inside the API Gateway which seem to work fine when testing them inside the web application.
I am then trying to call the functions inside an iOS application which is set up using the mobile hub. The functions also work inside the testing facility via the mobile hub perfectly fine, however when I actually test the functions inside the app I get:
"message" : "Internal server error"
I know the error is not much to work from, but I can't figure out a way to get a more detailed error description.
Any ideas?
This may happen because your Lambda function is not set to return a HTTP status code.
Changing from
exports.handler = (event, context, callback) => {
callback(null, 'Hello from Lambda');
};
to
exports.handler = (event, context, callback) => {
callback(null, { statusCode: 200, body: 'Hello from Lambda' });
};
Should fix the issue.
The JSON.stringify() solved my issue. The response.body needs to be in String format and not as JSON. I hope this helps.
exports.sendRes = (body, status = 200) => {
var response = {
statusCode: status,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(body)
};
return response;
};
I had the same issue with the following code:
exports.handler = async event => {
console.log("hello world");
return {
statusCode: 200,
body: event
};
};
To fix all I had to do was JSON.stringify() the body.
exports.handler = async event => {
console.log("hello world");
return {
statusCode: 200,
body: JSON.stringify(event), // <-- here
};
};
I had this problem until I click in "Deploy API" under the "Actions" button.
The other possible reason could be the payload/request/response limits on API Gateway (10MB) and/or Lambda (6MB)
None of the above answers worked for me. I was having a permission issue. Below is how I solved it.
Context
This is my lambda function:
exports.handler = function(event, context, callback) {
callback(null, {
statusCode: '200',
body: JSON.stringify({ 'message': 'hello world' }),
headers: {
'Content-Type': 'application/json',
},
});
};
I used terraform to provision api gateway and lambda. I used the example code provided by this blog post.
Diagnosis
In the lambda console I ran a test event on my lambda. As my lambda was super basic I used the hello world test template, named, and saved it. The test return success.
I checked cloudwatch logs, but couldn't find anything of use. I'm new to AWS so wasn't sure if I had to set anything up.
In the api gateway console I ran a test event. I just added Content-Type:application/json to the headers of the event and ran the test. For whatever weird reason the test results returned on the right side of the browser so had to scroll to the right to see them.
I got this result: Execution failed due to configuration error: Invalid permissions on Lambda function
SOLUTION
I checked the basic terraform example for api gateway and lambda integration here and noticed I was missing the aws_lambda_permission resource. This is needed to give permission to api gateway to invoke the lambda function.
For those that aren't using terraform here is a link to the aws docs on how to create the appropriate permissions.
please try to
Give execute lambda permission API Gateway
tick checkbox : Use Lambda Proxy integration
Handle null pointer for query string, headers & body.
I solved the issue by adding "isBase64Encoded": False/True to my lambda response
results = {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps(res),
"isBase64Encoded": False
}
In my case, the issue resolved while adding the integration Response and redeploying API
I'm trying the make further requests to linkedinAPI and to do so I need both token and token_secret.
I have several test accounts in linkedin, the login process success with all of them, however the token_secret stores (for all of them is empty).
Is that an error? I suspect so because using the pair token/token_secret in subsecuent oauth2 calls I get the following from linkedin
{ "errorCode": 0, "message": "[unauthorized]. The token used in the OAuth request is not valid. AQVvM2f2qefU3vULPS-R46DXN8Mnra9ImG14hzeTvMMcXvBVOEiUl4RTZCJrdFZoTfGGN1fFzLvxG-O_UWB8s8EDr35ZsgwW59y4KilndoEkr105Sg2GR90jmUxpqxU572IiARjN5gxAjfoWC4-_UupKlEtafQn23XQqvXeuLvE-FsPAaSA", "requestId": "VOAL1ULK4X", "status": 401, "timestamp": 1395348629428 }
Further details:
I check these tokens using the shell:
from allauth.socialaccount.models import SocialToken
map(lambda st: st.token_secret, SocialToken.objects.all())
And I get empty output:
[u'', u'', u'']
I found a solution myself so I'll explain it.
I'm not very into oauth2 so I don't know about the process neither if it was normal to have an empty secret_token. So I debugged a bit into the django-allauth code, and I saw that the requests they perform use only the token (no secret token)
Then I changed the library and started using the same they do: requests. And with the following simple script I can make any other request to the linkedin API:
def see_my_groups_json(request, url):
import requests
token = SocialToken.objects.get(account__user_id=request.user.pk)
resp = requests.get(url, params={'oauth2_access_token': token.token})
return resp.json()
You should check the SCOPE parameter for linkedin provider. For example, the next configuration requests permission for accessing user's email address, basic profile and to read and share updates on behalf of the user.
SOCIALACCOUNT_PROVIDERS = {
'linkedin_oauth2': {
'SCOPE': ['r_emailaddress', 'r_basicprofile', 'rw_nus'],
'PROFILE_FIELDS': ['id', 'first-name', 'last-name', 'email-address', 'picture-url', 'public-profile-url']
}
}
If after the token generation, we try to make an API call that requires some other privilege, we will get a 401 status code HTTP response.
django-allauth, by default, r_emailaddress scope or none at all, depending on whether or not SOCIALACCOUNT_QUERY_EMAIL is enabled.
Hope this helps you.