This is a follow up to a previous question I had posted here.
Basically I've been trying to implement a way to send request to twitter oauth resources via javascript. I have a server running a Django application which uses Django-social-auth to register users to Tiwtter. After I've obtained authorisation I get a users access_token and oauth_token_secret.
On the client side I have a javascript application which calls my server to compute the appropriate headers, which I do by using python oauth2. The piece of code doing this is as follows:
url = request.POST['url']
params = {
'oauth_version': "1.0",
'oauth_nonce': oauth.generate_nonce(),
'oauth_timestamp': int(time.time()),
}
at = social.extra_data['access_token'].split('&oauth_token=')[1]
ats = social.extra_data['access_token'].split('&oauth_token=')[0].split('oauth_token_secret=')[1]
token = oauth.Token(key=at, secret=ats)
consumer = oauth.Consumer(key=settings.TWITTER_CONSUMER_KEY, secret=settings.TWITTER_CONSUMER_SECRET)
params['oauth_token'] = token.key
params['oauth_consumer_key'] = consumer.key
req = oauth.Request(method="GET", url=url, parameters=params)
signature_method = oauth.SignatureMethod_HMAC_SHA1()
req.sign_request(signature_method, consumer, token)
This request parameters are then sent to the client which does the call to Twitter using these parameters:
$.ajax({
url: "https://api.twitter.com/1/statuses/home_timeline.json",
data: parameters,
dataType: 'jsonp',
success: function(twitter_data) {
console.log('twitter_data = ', twdata);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('err = ', textStatus);
console.log('err = ', errorThrown);
}
});
which generates a request for a resource like:
https://api.twitter.com/1/statuses/home_timeline.json?callback=jQuery17107030615725088865_1341786299930&oauth_nonce=15094349&oauth_timestamp=1341785696&oauth_consumer_key=[OAUTH_CONSUMER_KEY HERE]&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_token=[OAUTH_TOKEN HERE]0&oauth_signature=pQwHlKmepgtym%2Ffj%2BupCGP8mv3s%3D&page=2&include_entities=true&_=1341786306712
Still I get a 401 Unauthorized error. I checked the code three times so am wondering if I missing something???
Thanks.
For requests which requires an authentication, you have to put the authentication parameters in a HTTP header called Authorization, not in the POST parameters. It is explained in the Twitter API documentation here : https://dev.twitter.com/docs/auth/authorizing-request.
Related
I have a Django web app that is using the Django REST framework to generate various API endpoints.
I can ensure only logged in users can view/read these endpoints, but now I am at the stage of development where I want users to post to the API using tokens. I have successfully done this, however, I have hard-coded the users token into the post request in Javascript... This worked for testing but obviously is not a good final solution.
Is it possible to request the current users token somehow? Could I then include this token in the POST request head automatically?
Thanks for any help/feedback in advance!!
EDIT:
I think I am close, but I am getting a few errors in my chrome console, and still can't retrieve token.
Console Errors:
toggleScript.js:25 Uncaught DOMException: Failed to execute
'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.
at getToken (http://127.0.0.1:8000/static/defaults/toggleScript.js:25:7)
at manageDefaults
(http://127.0.0.1:8000/static/defaults/toggleScript.js:62:5)
at HTMLInputElement.onclick (http://127.0.0.1:8000/defaults/:1:1)
getToken # toggleScript.js:25
manageDefaults # toggleScript.js:62
onclick # (index):1
toggleScript.js:24 POST http://127.0.0.1:8000/api-token-auth/ 415
(Unsupported Media Type)
I have a button when pressed, will trigger the function to retrieve the token, and this is what is causing the error stack above.
toggleScript.js
function getToken(){
var xhr = new XMLHttpRequest();
var url = 'http://127.0.0.1:8000/api-token-auth/';
xhr.open("POST", url, true);
var data = JSON.stringify({"username": "myusername", "password": "mypassword"});
xhr.send(data);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.token);
}
};
}
Django Rest Framework provides an API endpoint for requesting a user's token, given a username and password. You can wire the view into your urls.py:
from rest_framework.authtoken import views
urlpatterns += [
url(r'^auth-token/', views.obtain_auth_token)
]
Then when you POST a valid username and password to that view it will return the token in a JSON response:
{ 'token' : '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b' }
Your app can then store that and send it in subsequent requests.
An example of retrieving the token using JQuery (assuming the view was mapped to the path ^auth-token/ in your urls.py):
$.post('/auth-token/', { username: 'admin', password: 'whatever' }, function(data) {
// Token available as data.token
});
If you try and post to the auth-token view from within an already authenticated session, Django will likely reject the request with a CSRF token missing or incorrect response. You should either ensure that the session is not authenticated when you retrieve the token, or you could potentially include the X-CSRFToken header in the request. You'd need to extract the value from the csrftoken cookie. For example (using JQuery and the JQuery Cookie plugin):
$.ajax({
url: "/auth-token/",
type: "POST",
headers: {
"X-CSRFToken": $.cookie("csrftoken") # Extract the csrftoken from the cookie
},
data:{ username: "admin", password: "whatever" },
dataType:"json"
}).done(function(data) {
// Token available as data.token
});
More info on obtaining an auth token here
I'm making a client application where the user must login using JIRA, similar like other apps where you grant permission to your credentials and access right away the application.
I followed the instructions and I'm setting up my client using this reference I'm sending my request to MY_BASE_URL + "/plugins/servlet/oauth/request-token" but I'm getting a empty response and a CORS error that the request didn succeded.
My question is consuming the api endpoints via javascript is even possible? , I searched a lot here and inside the forums of Atlassian and I the only thing I found is this question which is unanswered.
$("#authenticate").click(function(){
jQuery.ajax({
//The URL to process the request
'url': BASE_URL+'/plugins/servlet/oauth/request-token',
'headers':{
'Access-Control-Allow-Origin':'*'
},
'type': 'GET',
'success': function (data) {
alert('Request token is: ' + data);
}
});
});
I am trying to perform actions on sendgrid lists via their API.
https://sendgrid.com/docs/API_Reference/Web_API_v3/Marketing_Campaigns/contactdb.html#List-All-Lists-GET
I'm using this to set up my code however I'm getting Error 401 UNAUTHORISED when performing the request via $http in my Angular app.
I tried making the same request in Python and that seemed to working fine though.
var head = {'Authorization': 'Bearer SG.PE-XXXXXXXXXXXXXXXXXXXXXX'};
var sgUrl = "https://api.sendgrid.com/v3/contactdb/lists";
self.$http({
method : "GET",
url : sgUrl,
headers : head,
}).then(function mySuccess(response) {
alert(1);
}, function myError(response) {
alert(0);
});
Thanks!
I am using AngularJS and trying to work with Google's reCAPTCHA,
I am using the "Explicitly render the reCAPTCHA widget" method for displaying the reCAPTCHA on my web page,
HTML code -
<script type="text/javascript">
var onloadCallback = function()
{
grecaptcha.render('loginCapcha', {
'sitekey' : 'someSiteKey',
'callback' : verifyCallback,
'theme':'dark'
});
};
var auth='';
var verifyCallback = function(response)
{
//storing the Google response in a Global js variable auth, to be used in the controller
auth = response;
var scope = angular.element(document.getElementById('loginCapcha')).scope();
scope.auth();
};
</script>
<div id="loginCapcha"></div>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
So far, I am able to achieve the needed functionality of whether the user is a Human or a Bot,
As per my code above, I have a Callback function called 'verifyCallback' in my code,
which is storing the response created by Google, in a global variable called 'auth'.
Now, the final part of reCAPCHA is calling the Google API, with "https://www.google.com/recaptcha/api/siteverify" as the URL and using a POST method,And passing it the Secret Key and the Response created by Google, which I've done in the code below.
My Controller -
_myApp.controller('loginController',['$rootScope','$scope','$http',
function($rootScope,$scope,$http){
var verified = '';
$scope.auth = function()
{
//Secret key provided by Google
secret = "someSecretKey";
/*calling the Google API, passing it the Secretkey and Response,
to the specified URL, using POST method*/
var verificationReq = {
method: 'POST',
url: 'https://www.google.com/recaptcha/api/siteverify',
headers: {
'Access-Control-Allow-Origin':'*'
},
params:{
secret: secret,
response: auth
}
}
$http(verificationReq).then(function(response)
{
if(response.data.success==true)
{
console.log("Not a Bot");
verified = true;
}
else
{
console.log("Bot or some problem");
}
}, function() {
// do on response failure
});
}
So, the Problem I am actually facing is that I am unable to hit the Google's URL, Following is the screenshot of the request I am sending and the error.
Request made -
Error Response -
As far as I understand it is related to CORS and Preflight request.So what am I doing wrong? How do I fix this problem?
As stated in google's docs https://developers.google.com/recaptcha/docs/verify
This page explains how to verify a user's response to a reCAPTCHA challenge from your application's backend.
Verification is initiated from the server, not the client.
This is an extra security step for the server to ensure requests coming from clients are legitimate. Otherwise a client could fake a response and the server would be blindly trusting that the client is a verified human.
If you get a cors error when trying to sign in with recaptcha, it could be that your backend server deployment is down.
I am currently developing a Facebook application on a website that would need to send a notification to the app's users without using a user interface dialog. After reading some blogs I concluded that the option is available in example in PHP API only. I could only find this example:
http://developers.facebook.com/docs/channels/
Is there a JavaScript API to do this?
After some sort of more reading, I found out that FB.api could handle graph object apis and also the rest apis which are to be deprecated, and I got the following working:
FB.api('/1175241653/apprequests', 'post',
{ message: "This is a Good Request!!" },
function (response) {
if (!response || response.error) {
alert('Error occured , Request Failed :(( ');
} else {
alert('Request is sent successfully');
}
});
However, that id number 1175241653 does not work if the logged in user's id is not that id.
Therefore this would required the same functionaliy that Facebook uses to retrieve the ID of whomever signed into the application. Is there any way to do this?
Now , I got this working in all means and I'd like to share it with those who may deal with :))
lets say 1st as to do a single app request from ur application to any of facebook registered users in your application would be like this:
var data =
{
message: "Hey there, something good happened over here !",
access_token: "AAADdf39DLxgBANEwZA9ZCfZCSbtdfcZBtstWMMsW5JiZBjVW2Ucx234sedhHSZCm8aEABzvhWPBNWi1bTKwZBq0EcgZD"
}
FB.api('/68751034/apprequests',
'post',
data,
function (response) {
console.log(response);
if (!response || response.error) {
} else {
}
});
access_token should be provided as to authenticate the request from the application to the registered user.
If you do not know about access tokens, you can read about it over at the facebook site:
http://developers.facebook.com/docs/authentication/
Also, if you want to send batch requests to a set of users in one request call, there's a support page from the facebook site about that too:
http://developers.facebook.com/docs/reference/api/batch/
and here's a sample of what I mean :
var _batch = [];
for (var i = 0; i < _socialids.length; i++) {
_batch.push({
method: 'post',
relative_url: _socialids[i] + '/apprequests/?access_token=' + _accessTokens[i],
body: "message= This is a request sent to many users" });
}
if (_batch.length > 0) {
FB.api('/', 'POST', { batch: _batch }, function (res) {
// Do whatever when the batch request is sent
});
}