I'm new to Instagram apps development and struggling with this issue for some time now. Basically, this is how it looks like:
I'm redirecting user to authorization url like this:
window.open("https://api.instagram.com/oauth/authorize/?client_id=" + igClientId + "&redirect_uri=" + igCallbackUrl + "&response_type=code", "_blank");
Then, when user will login, page reloads and Instagram CODE is added at the end of callback url ('?code=returned_by_instagram_code').
And this is the place where I've stuck.
How can I obtain returned code from url after page reloads (it is stored in cookies or session so I could access it in some way, or should I get it somehow through callback url and some function attached to it)?
How next, when I'll obtain the code, can I send (POST) request to Instagram for access_token?
Thank you in advance for any help.
PS. I'm using javascript without any frameworks (e.g. jquery) and this is the response that I'm looking for.
From the documentation on using Client-Side access token generation only (http://instagram.com/developer/authentication/) and the key thing you need to change is the responsecode in your URL to be: &response_type=token
Client-Side (Implicit) Authentication
If you’re building an app that does not have a server component (a purely javascript app, for instance), you’ll notice that it’s impossible to complete step three above to receive your access_token without also having to ship your client secret. You should never ship your client secret onto devices you don’t control. Then how do you get an access_token? Well the smart folks in charge of the OAuth 2.0 spec anticipated this problem and created the Implicit Authentication Flow.
Step One: Direct your user to our authorization URL
https://instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECTURI&response_type=token
At this point, we present the user with a login screen and then a confirmation screen where they approve your app’s access to their Instagram data. Note that unlike the explicit flow the response type here is “token”.
Step Two: Receive the access_token via the URL fragment
Once the user has authenticated and then authorized your application, we’ll redirect them to your redirect_uri with the access_token in the url fragment. It’ll look like so:
http://your-redirect-uri#access_token=270740070.f59def8.d58713f2c81741c5b3686109306f98b4
Simply grab the access_token off the URL fragment and you’re good to go. If the user chooses not to authorize your application, you’ll receive the same error response as in the explicit flow
A simple example, get your token in registration app on api.instagran (https://instagram.com/developer/clients/register/). Make your login before:
var accessToken = '5e6e329062f047dd95ggj6c9df202c828';
$.ajax({
url: 'https://api.instagram.com/v1/media/popular',
dataType: 'jsonp',
type: 'GET',
data: {client_id: accessToken},
success: function(data){
console.log(data);
for(x in data.data){
$('ul').append('<li><img src="'+data.data[x].images.low_resolution.url+'"></li>');
}
},
error: function(data){
console.log(data);
}
});
The igCallbackUrl will redirect to a page. The code can be accessed as a GET parameter to that request.
Something like GET['code'] in php. If you give more details about the Server side framework then it will be helpful to answer your qwery.
You can use github.com/Instagram/instagram-javascript-sdk if you are using on Javascript.
Related
I have a .cshtml page, where a click on a button calls an API
Currently, my JS code looks like :
var headers = {};
headers["Authorization-Token"] = '#Model.ApiToken';
$.ajax({
url: "my-url",
type: "GET",
headers: headers
});
However, if the end-user opens the browser console, goes to the Network tab, searches for the generated cshtml, he can see :
var headers = {}
headers[Authorization-Token] = 'my_token'
The token can be seen in clear text
I can't call my API without this header, as the call is immediately rejected if the header is not present.
Is there a way to hide it to the end-user, and if so, how ?
Thank you
It is better to keep the tokens outside the browser, one option is to store the token inside the cookie (encrypted of course). ASP.NET Core can handle that for you automatically. Or in the backend as part of the user session.
An perhaps better option is to look at using the Backend For Frontend (a.k.a BFF) pattern to secure SPA applications.
See
Backend For Frontend Authentication Pattern with Auth0 and ASP.NET Core
The BFF Pattern (Backend for Frontend): An Introduction
Securing SPAs using the BFF Pattern (once and for all)
Users of my web application are expected to provide bug reports as a GitHub issue, with a pregenerated title and body.
This works perfectly fine using GET for small bodies:
const title = getLastErrorTitle();
const body = getAllTheLogMessages();
window.open(`https://github.com/theuser/therepo/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}`);
If the user is logged in, GitHub presents the user with a new issue with the title and body already filled out, perfect. If not, GitHub prompts the user to log in and it works the next time.
However, if the body is too large, the GET request fails because the URL becomes too long.
After consulting the manual I tried doing the same with POST but I get a 404 from GitHub with the following test request (jQuery for brevity):
$.ajax({
type: "POST",
url: "https://api.github.com/repos/theuser/therepo/issues",
data: data = {title: "Test", body: "Test Body"},
});
My suspicion is, that the GitHub API was not designed with my use case in mind, but that POST always requires authentication and creates the full issue in one go, without letting the user change it beforehand like it is possible with GET.
How can I transfer the functionality of the GET method over to the POST method? I just want GitHub to present the user, that is currently logged in inside the browser, with a prefilled issue, without needing a token.
You can't. Otherwise, it would be a major CSRF exploit.
However, you can use OAuth authentication that will allow your application to use some features : https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/
Or simply, redirect the user to a new issue page (for exemple with a simple HTML link <a>) with some automatic content, using this pattern :
https://github.com/{theUser}/{theRepo}/issues/new?body={theContentYouWhant}&title={theTitleYouWhant}
Example : https://github.com/CristalTeam/php-api-wrapper/issues/new?body=Hi,%20this%20is%20the%20body%20you%20want&title=Hello,%20this%20is%20a%20prefill%20issue
What I would suggest here is to generate a personal_auth_token at gihub and pass this token in the headers under Authorization field.
To generate personal_auth_token, login to github.com, go to settings -> developers settings -> Personal access tokens and generate one.
Pass this token in headers under Auhtorization: token. So in your AJAX request, it could look something like this:
$.ajax({
url: *yourUrl*
...
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', *token*));
},
});
One thing to note here is each of the developers POSTing to the repo will be requiring to generate their access token and you can't push this token on to a public Github repository because of obvious security breach. If you accidentally do so, the token is revoked immediately and you'll be required to create a new one.
I need to retrieve a facebook page's list of posts (feed) using their javascript SDK, just like they explain in their docs: https://developers.facebook.com/docs/graph-api/reference/v2.4/page/feed
/* make the API call */
FB.api(
"/{page-id}/posts",
function (response) {
if (response && !response.error) {
/* handle the result */
}
}
);
I need it to be my website's "news section", so users should see it even if they are not connected to facebook.
The problem
Cool, but there is a problem... It returns: An access token is required to request this resource.
Holy cow... I'd like to get some access token for you #facebook, but my app doesn't make use of your authentication tools/plugins.
ANYWAY, I tried with FB.getLoginStatus(); but doesn't work, because the only way it can return an access_token is if the user is actually connected to the application. My users may not even be logged to facebook!
So, ¿How can I get an access_token to be stored into a variable, and later be used to get /{my-page}/posts?
I've already payed a look to this SO question, but it doesn't solves my problem, simply because there are no such "generic tokens".
I've also read https://developers.facebook.com/docs/facebook-login/access-tokens/ and that also relies on tokens generated through facebook login methods... So, can't I display a list of fb page's posts in my website, without being connected into facebook, hence an application?
ADD: My app is build with angularJS, I'm not dealing with server-side code. I shall rely purely on javascript methods.
You could either use an page or an app access token, but as you'd be using them on the client-side, neither of them are an option.
See
https://developers.facebook.com/docs/facebook-login/access-tokens#apptokens
https://developers.facebook.com/docs/facebook-login/access-tokens#pagetokens
Note that because this request uses your app secret, it must never be made in client-side code or in an app binary that could be decompiled. It is important that your app secret is never shared with anyone. Therefore, this API call should only be made using server-side code.
I'd strongly recommend to build a simple server-side script (PHP for example) to proxy the request to the Graph API. You could then call this via AJAX for example and load the posts asynchronously (and alse get rid of the FB JS SDK!). There is NO way to handle this in a secure manner if you don't want to use FB Login for all of your users (which also doesn't make much sense IMHO).
I think it's straightforward :)
Since pages' posts are always public, it only needs a valid access token to retrieve page posts.
Quoting what you've written:
So, ¿How can I get an access_token to be stored into a variable, and later be used to get /{my-page}/posts?
You only require an access token.
My suggestion would be;
- Generate an access token for yourself (no extra permission needed)
- request page-id/posts
This way you don't require other users to be connected to facebook, you can simply requests page-id/posts to retrieve posts with access token you generated for yourself.
I hope it solves your problem :D
TIP: As long as posts are public, you only require a valid access token, it doesn't need to be user or page specific.
I have an input field on my webpage that I would like to allow users to tweet. I know I can do this using Oauth but because I am using JavaScript it is insecure since my id and secret would be visible. Is there a better way to do this?
The way I am doing it now is something like this:
var accessor = {
token: "...",
tokenSecret: "...",
consumerSecret: "..."
consumerKey : "...",
};
//create message with input field text
var message = {
action: url,
method: "GET",
parameters: {...}
};
OAuth.completeRequest(message, accessor);
OAuth.SignatureMethod.sign(message, accessor);
url = url + '?' + OAuth.formEncode(message.parameters);
But this will make my secrets visible.
Thanks
In the OAuth model, there are three parties: the server or "resource manager," the app or "client", and the user or "resource owner".
In your case, the "client" is the web app, the thing you are building. The resource manager is twitter, and the user is the resource owner. Maybe it bears repeating: the resource that is owned and managed is the tweet stream.
OAuth allows the client to submit requests to the resource manager on behalf of the resource owner. Translated to your scenario, that means your app (web app) can submit tweets on behalf of the user.
The web app model and its distributed computational model, with some code running on the server (PHP, Ruby, ASPNET, or whatever it is) and some code running on the client (Javascript) sort of confuses the issue a little.
As you point out, you can "do" oauth by embedding the key and secret in JS code. You rightly point out that this exposes stuff you don't want to expose.
The obvious alternative is to embed that stuff into the server-side code. This requires that the connection to twitter occur between the server and twitter, not between the browser and twitter.
When the user wants to tweet, use an ajax call from the browser to a piece of code on your server, let's call it mytweet.php. This is a script you write, which then does the OAuth dance and sends a status update to twitter.com on behalf of the user.
ya follow?
FIXED NOW! But I can't answer my own question yet. See my comment below. And thanks for helping.
I've searched and searched and read the docs and still can't figure this out.
I have a web page about an event. There's also a public Facebook "event" for my event. I'm trying to use the FB Javascript SDK to get the number of attendees for the Facebook event and add it to the number of people who've registered through the website.
I've created an app and I have an appID and secret string. I can get an access token from:
https://graph.facebook.com/oauth/access_token?client_id=XXXX&client_secret=XXXXX&grant_type=client_credentials
and I can then use that access token to get the attendees for a public event:
https://graph.facebook.com/331218348435/attending?access_token=XXXXXXXXX
That's all fine.
I'm now trying to do this same thing using the Javascript SDK.
I've loaded the SDK and done an init:
FB.init({
appId : 'XXXXXXXX',
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
and I know the SDK is working because I can get an object with the data that doesn't need an access token:
FB.api( '/331218348435', function (response) { console.log ( response ) } );
but when I try to get the attendee data that needs the access token:
FB.api( '/331218348435/attending', function (response) { console.log ( response ) } );
I get an OAuthException: "An access token is required to request this resource."
All the tutorials and information I can find all refers to using the .login method, but I don't want a user to login, I want to login using my app ID without any user interaction.
I'd assumed that the API took the SDK's init request and granted me an access token when I called the .init method, the authentication being done against my website's address (the HTTP referrer - yes I have set my website URL in the Facebook app settings).
Any ideas what might be causing this to not work? How can I get the access token using the Javascript SDK without doing a .login? Am I missing a step? Is this even possible?
Thanks
Form what the rather circular documentations says, getting the attending feed requires a 'generic access_token`. In Facebook terms:
Any valid access_token
Any valid access token returned by our APIs. An access token may not be valid if, for example, it has expired. No special permissions are required. Occasionally, this is referred to as a generic access_token.
So this means that you can use any token you like to access the attending feed, as long as the event is public. The easiest access token to get seems to be an app token: http://developers.facebook.com/docs/authentication/#applogin. You can get this token using only your App ID and Secret, and no user interaction is required.
To summerise the link content: You can get an application access token by sending a GET request to
https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&grant_type=client_credentials
You can then use that access_token to make the call for you attending list
FB.api('MyEvent/attending?access_token=ACCESS_TOKEN');
Oh. OK.
Well, for whatever reason, I went away and had my dinner and when I come back it's working fine.
When I updated the settings for my app Facebook said it might take a few minutes for the change to get around the servers. Turned out to take over an hour!
My code was fine.
Thanks for your help.