How do I handle html response from oauth2 token request? - html

In my angular 6 application, I’m trying to send a request to get an access token from an oauth2 provider called anilist. I’m doing it like this:
this.http.get(url, options).subscribe(result =>
{
console.log('result: ', result);
});
…where http is imported like this:
import { HttpClient } from ‘#angular/common/http';
This results in an error:
SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse
This seems to be because the request is returning an html document (most likely the login page) and it obviously can’t parse it as json.
But then my question is: how does one send a request for an oauth2 token and handle the response as an html page?
Thanks.

It is a bit strange that you want to get access token via http get.
Maybe that is the problem, are you talking about this site? https://anilist.co/
https://anilist.gitbook.io/anilist-apiv2-docs/overview/oauth/authorization-code-grant
The user navigates to their site via your oAuth2 signin link
They sign in, add grant, then the browser redirects to your callback url
You change your auth code to access token via http post request. https://anilist.gitbook.io/anilist-apiv2-docs/overview/oauth/authorization-code-grant#converting-authorization-codes-to-access-tokens
I think you get an html response because
You try to get access token via http get - and here you get an unsupported method / 404 / etc error
Or you are trying to get your access token from the anilist's login page (anilist.co/api/v2/oauth/authorize) instead of the token endpoint (anilist.co/api/v2/oauth/token)
Update
It is the same case, if you are using implicit grant (because you said you are creating an angular app, which can be an SPA - therefore a public client, but in this case the access token is provided in the response) https://anilist.gitbook.io/anilist-apiv2-docs/overview/oauth/implicit-grant

Related

Viewer loadModel - route with JWT authentication

My current stack is React-Native that uses a WebView with forge(v7.15) in it. My API is a symfony API and it has a authenticated route that receives the filename and returns me a BinaryFileResponse based on the file.
Basically what I'm wanting to do is:
actual:
viewer = new Autodesk.Viewing.Private.GuiViewer3D(document.getElementById('forgeViewer'));
viewer.loadModel('API_URL/route/filename');
expected:
viewer = new Autodesk.Viewing.Private.GuiViewer3D(document.getElementById('forgeViewer'));
viewer.loadModel('API_URL/route/filename', jwtToken); //or something like that.
Atm, everything works fine.
But I want to change the route to be authenticated and I don't know how I can do that, and if I can do that.
I have my JWT token saved on client-side and I want to pass it on header/or anything that helps me to achieve that.
Is there a way to use the loadModel and send a JWT token to the URL that viewer will try to load?

Google OAuth - Incorrect JSON while Validating Access Token

I'm getting an access token from the Android SDK which I'm sending to the server. On the server side, I'm calling the following API to validate my token:
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=<token here>
From Google, I'm getting the following response (partial response added):
{\"statusCode\":200,\"body\":\"{n \"issued_to\":
\"407408718192.apps.googleusercontent.com\",n \"audience\":
\"407408718192.apps.googleusercontent.com\",n \"user_id\":
\"110586055381870434283\",n \"scope\":
\"https://www.googleapis.com/auth/plus.login
https://www.googleapis.com/auth/plus.me"}
Unfortunately, this JSON is not parseable because of the backslashes & i'm not able to validate the token identity.
Is this a problem with the Google API or do I need to apply any regex?
Google sends back proper JSON without the slashes, being exactly the part that's inside the "body" element of the output that you paste (well without the slashes).
So your Node.js HTTP client is wrapping it with the HTTP status code element and puts in the slashes as well, so your clients need convert back from that on its own.

unexpected token : from angular $http.jsonp request to Instagram API

I'm making a request to an authorized Instagram account to display images on a site. Originally, I was running into No 'Access-Control-Allow-Origin' when using Angular's $http.get(....
From Matt's answer in this question, It seems that I can use getJSON, or Angular $http.jsonp, to bypass this issue. That Guy's answer also says "JSONP is really a simply trick to overcome XMLHttpRequest same domain policy".
So, I'm no longer getting that problem, and am getting a json payload:
{"pagination":{"next_url":"https:\/\/api.instagram.com... etc
But am getting a very ambiguous error:
Uncaught SyntaxError: Unexpected token :
This is a response from the Instagram API, so I'm not sure why there'd be a syntax error on the inbound json. Also, It's hard to locate the error since the jsonp response is all on a single line... where the error is reported.
The preview shows that I'm getting a full payload:
I found the issue. Unfortunately there are no JavaScript libraries to help with this, but in the Instagram API docs, for JSONP you can wrap the response with a callback so that the json payload will be wrapped in <script> tags (more info on jsonp here), therefore not blocked by Access Control Allow Origin.
https://api.instagram.com/v1/tags/coffee/media/recent?access_token=ACCESS-TOKEN&callback=callbackFunction
Response:
callbackFunction({
...
});
So, in your http request URI, you add in a callback parameter. Since I am using Angular, their docs for $http.jsonp() requests specify the callback string as "JSON_CALLBACK".
So, my request URL for Angular would be:
$http.jsonp(
'https://api.instagram.com/v1/tags/coffee/media/recent?
access_token=ACCESS-TOKEN&callback=JSON_CALLBACK')
.success(function(data) {...

Not able to fetch the json response through angularjs

Need to fetch the build values from apache.org. So i am using their api
https://builds.apache.org/api/json
I tried angularjs $http.jsonp but not able to fetch the data.
In chrome console under network json api is getting loaded but the data is not getting returned instead it is throwing the response as error.
app.controller("jsoncontroller",function($scope,$http){
var url='https://builds.apache.org/api/json';
$http.jsonp(url).success(function(data){
console.log('success');
})
.error(function () {
console.log('error')
});
});
Getting the error as
Uncaught SyntaxError: Unexpected token :
error
As per the jsonp angular docs, you must append JSON_CALLBACK to the URL: https://builds.apache.org/api/json?jsonp=JSON_CALLBACK
However, that URL doesn't work because even when the callback parameter is specified, the server still sends back a content-type of application/json, instead of the expected application/javascript. This causes it to be parsed (evidently) by the json parser instead of the javascript callback needed for JSONP to work. I'm not versed enough in JSONP or Angular to know who is it fault here.
I've made a fiddle with this working with another URL.
[Update]: The apache build server appears to use Jenkins, which has disable JSONP from the remote API. You can verify this yourself by trying to hit their jsonp endpoint, which returns a 403. You'll have to use another endpoint, no way I can see around this.

How can I access auth-only Twitter API methods from a web application

I have a web application for iPhone, which will ultimately run within a PhoneGap application - but for now I'm running it in Safari.
The application needs to access tweets from Twitter friends, including private tweets. So I've implemented OAuth using the Scribe library. I successfully bounce users to Twitter, have them authenticate, then bounce back.
At this point the web app has oAuth credentials (key and token) which it persists locally. From here on I'd like it to user the Twitter statuses/user_timeline.json method to grab tweets for a particular user. I have the application using JSONP requests to do this with unprotected tweets successfully; when it accesses the timeline of a private Twitter feed, an HTTP basic authentication dialog appears in the app.
I believe that I need to provide the OAuth credentials to Twitter, so that my web application can identify and authenticate itself. Twitter recommends doing so through the addition of an HTTP Authorization header, but as I'm using JSONP for the request I don't think this is an option for me. Am I right in assuming this?
My options therefore appear to either be putting the oAuth credentials as query-string parameters (which Twitter recommends against, but documentation suggests still supports); or proxying all the Tweets through an intermediate server. I'd rather avoid the latter.
I access the Twitter API using URLs of the form
http://api.twitter.com/1/statuses/user_timeline.json?user_id=29191439&oauth_nonce=XXXXXXXXXXX&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1272323042&oauth_consumer_key=XXXXXXXXXX&oauth_signature=XXXXXXXXXX&oauth_version=1.0
When user_id is a public user, this works fine. When user_id is a private user, I get that HTTP Basic Auth dialog. Any idea what I'm doing wrong? I'm hoping it's something embarrassingly simple like "forgetting an important parameter"...
The oAuth stanza needs to be exact, as per http://dev.twitter.com/pages/auth#auth-request - I ended up building an Authorization: header that I could first check with curl.
I built it using the really helpful interactive request checker at http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iv-signing-requests/
Here's a friends API request for a protected user:
curl -v -H 'Authorization: OAuth realm="https://api.twitter.com/1/friends/ids.json", oauth_consumer_key="XXXXXXXXXXXXXXXX", oauth_token="XXXXXXXXXXXXXXXX", oauth_nonce="XXXXXXXXXXXXXXXX", oauth_timestamp="1300728665", oauth_signature_method="HMAC-SHA1", oauth_version="1.0", oauth_signature="XXXXXXXXXXXXXXXX%3D"' https://api.twitter.com/1/friends/ids.json?user_id=254723679
It's worth re-iterating that as you've tried to do, instead of setting the Authorization header via e.g. jquery's beforeSend function, that for cross-domain JSONP requests (which can't add HTTP headers) you can make oAuth requests by putting all the relevant key/value pairs in the GET request. This should hopefully help out various other questioners, e.g
Set Headers with jQuery.ajax and JSONP?
Modify HTTP Headers for a JSONP request
Using only JQuery to update Twitter (OAuth)
Your request looks like it has a couple of problems; it's missing the user's oauth_token plus the oauth_signature doesn't look like it has been base64 encoded (because it's missing a hex encoded = or ==, %3 or %3D%3D respectively).
Here's my GET equivalent using oAuth encoded querystring params, which you can use in a cross-domain JSONP call:
https://api.twitter.com/1/friends/ids.json?user_id=254723679&realm=https://api.twitter.com/1/friends/ids.json&oauth_consumer_key=XXXXXXXXXXXXXXXX&oauth_token=XXXXXXXXXXXXXXXX&oauth_nonce=XXXXXXXXXXXXXXXX&oauth_timestamp=1300728665&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_signature=XXXXXXXXXXXXXXXX%3D
I was struggling with similar problem of making JSONP requests from Jquery, the above answer helped just to add what I did to achieve my solution.
I am doing server to server oauth and then I send oauth token, secret, consumer key and secret (this is temporary solution by the time we put a proxy to protect consumer secret). You can replace this to token acquiring code at client.
Oauth.js and Sha1.js download link!
Once signature is generated.
Now there are 2 problems:
JSONP header cannot be edited
Signed arguments which needs to be sent as part of oauth have problem with callback=? (a regular way of using JSONP).
As above answer says 1 cannot be done.
Also, callback=? won't work as the parameter list has to be signed and while sending the request to remote server Jquery replace callback=? to some name like callback=Jquery1232453234. So a named handler has to be used.
function my_twitter_resp_handler(data){
console.log(JSON.stringify(data));
}
and getJSON did not work with named function handler, so I used
var accessor = {
consumerSecret: XXXXXXXXXXXXXXXXXXXXXX,
tokenSecret : XXXXXXXXXXXXXXXXXXXXXX
};
var message = { action: "https://api.twitter.com/1/statuses/home_timeline.json",
method: "GET",
parameters: []
};
message.parameters.push(['realm', "https://api.twitter.com/1/statuses/home_timeline.json"]);
message.parameters.push(['oauth_version', '1.0']);
message.parameters.push(['oauth_signature_method', 'HMAC-SHA1']);
message.parameters.push(['oauth_consumer_key', XXXXXXXXXXXXXXXX]);
message.parameters.push(['oauth_token', XXXXXXXXXXXXXXX]);
message.parameters.push(['callback', 'my_twitter_resp_handler']);
OAuth.completeRequest(message, accessor);
var parameterMap = OAuth.getParameterMap(message.parameters);
Create url with base url and key value pairs from parameterMap
jQuery.ajax({
url: url,
dataType: "jsonp",
type: "GET",
});