I want to make something like an instagram web viewer like http://www.imgrum.org
Now, when I open https://www.instagram.com/developer/
I see that instagram requires some authentication from every user to access their images, but I have never authorized imgrum, yet my images etc. are visible on imgrum.org. How are they doing it? Or am I misinterpreting instragram API documentation?
You don't need authentication from a specific user to access that specific user's public content via the API.
In order to access public Instagram content via the API, you just need to authenticate any single Instagram account.
Once you authenticate any Instagram account, you can, through the access token for that account, access most of the public Instagram content.
As a concrete example, here are 2 GET requests you can make with a single user access token:
1) Request recent images of the user whose access token you have.
https://api.instagram.com/v1/users/self/media/recent/?access_token=ACCESS-TOKEN
Note here the self: meaning the user whose access token is ACCESS-TOKEN.
2) Request recent images of any other user on Instagram with a public account.
https://api.instagram.com/v1/users/{user-id}/media/recent/?access_token=ACCESS-TOKEN
Note here the {user-id} in place of self: meaning you can enter any user-id for any public Instagram account. And also note that this request still requires an ACCESS-TOKEN, but that the user associated with the ACCESS-TOKEN does not have to be the same user associated with user-id.
This is all documented here:
https://www.instagram.com/developer/endpoints/users/
https://www.instagram.com/developer/authentication/
Update:
In order to make the 2nd API call I listed above to any {user-id}, you need the ACCESS-TOKEN (of the authenticated user) to include public-content as part of the scope. In order to get that, your app must be approved by Instagram.
Related
I've checked many resources, and most of them claim the only way to fetch users media using an token is to create facebook app, add instagram, generate user token for yourself and fetch graph api. https://graph.instagram.com/me endpoint. Is there no other way to simply fetch user's media via official api by using access token and username?
Also, when I use /me endpoint, everything works. If I change it to /*myusername*, where I obviously put my username instead, it says that said object does not exist, cannot be loaded due to missing permissions, or does not support this operation.
So, no. If you want to use Instagram API to fetch regular( ie not business ) users' feed, you need to use Instagram Basic API.
I'm using authentication code mechanism through Docusign's API for integration and works as expected.
Have a question regarding the documentation about implementation best practises, described in this page
Questions are related to the diagram at the end:
Question1
In Get the user's account ID, base URL and name (1st square) how do you recommend fetching the user/account information as before consent we don't know who is giving consent?
If it is related to users that may have given consent before, is it even necessary? If tokens already exist for the user, what is the purpose of verifying this scenario?
In the documentation it seems this is reinforced further with what is stated next:
How will we know what is the account/user information before the user gives consent?
Question2 (Similar to above)
In Collect the account ID (GUID) and name of the user, when no access token is found, I'm assuming we should redirect the user immediately so that the use gives consent again. Similar to the question above, in the diagram it indicates we should do this action "Collect account/user info" somehow before redirect for consent? We only know it afterwards as well, so is it needed?
It would be great if it would be possible to clarify the above!
As Inbar commented, that diagram needs some work. I'm sorry for the confusion.
Here's my recommendations for user present (Authorization Code and Implicit grant flows) and user absent (JWT grant flow).
All authorization flows
Determine if your users will typically use your application with a particular eSignature account or with any of their accounts. (It is common for customers to have access to more than one DocuSign eSignature account.)
If a particular account will be used, then provide an installation screen for your app where the admin can enter the account ID (use the guid format).
Your installation screen should also enable the installer to set
the DocuSign OAuth service provider, either production account.docusign.com or demo account-d.docusign.com
User present: Authorization Code and Implicit grant flows
Your app may or may not have its own login sequence for users. Your app needs a DocuSign access token for making API calls to DocuSign APIs.
When your user wants to authenticate with DocuSign:
Start the Authorization Code or Implicit grant flow.
When the flow is done, your app has an access token.
If the Authorization Code grant flow was used then you also have a refresh token.
Use the oauth/userinfo API call to obtain information about the user:
Their name and email
The eSignature accounts they have access too, and which of those accounts is the user's default account
For each account, the name of the account and the baseUrl for making API calls to the account.
If your app's users use a preferred account, then check that the user has access to the preferred account. Else, note the account id of the user's default account. (Also be prepared to handle the cases where there is either no userinfo response, no account or no default account for the user. These are infrequent DocuSign errors and can be fixed by contacting DocuSign Customer Support and referencing this article.
Use the expires_in OAuth response attribute to calculate your expires datetime. Then subtract 10 minutes so you have a buffer between the time you'll last use the access token and when it actually expires. You now have the last_use time.
Store the user's information, including the account id, base url for the account, access token, and last_use datetime.
If you have a refresh token, store it (and the user's information) in non-volatile storage.
When your application wants to make an API call
If you have a current access token for the user (last_use datetime is after the current datetime) then use it.
If the last_use time has passed, then use the refresh token if you have it. When refreshing the toke, you'll receive a new refresh token. Store it in non-volatile storage, overwriting the prior refresh token.
If no refresh token, then your app will need to ask the user to authenticate again.
Do not use oauth/userinfo again after either the token was refreshed or the user authenticated again. Keep and use the userinfo obtained after the person first logged in.
When your user wants to use a different account
Provide a "Switch accounts" feature to enable users to choose which of their accounts should be used. (Only applies if any account can be used with the application.)
User not-present: JWT grant
Your app's configuration screen will also need the user id in guid form. You can either store these values or look them up from DocuSign.
Decide whether a specific account is needed or not (see above).
Decide how the user will grant consent. See this video for more info.
First time your app needs an access token after a reboot
Use the JWT user grant to obtain an access token
As above, calculate the last_use datetime including a 10 minute buffer.
Use oauth/userinfo as above to determine if the user has access
the account or what the user's default account is. Also obtain the account's base_url.
Store the information.
Use the access token to make the API call.
Subsequent API calls
Check the last_use datetime. If it hasn't yet occurred then use the stored access token. If it has occured, then redo the JWT user grant flow but do not make another oauth/userinfo call--use the prior information.
Question 1 - You do not need to remember which user gave consent. That is not something you should do anyway, because users can revoke consent and then your information will be inaccurate. The system will ask for consent if needed (and if you ask for additional scopes it may be needed even if consent was given for example).
Question 2 - You should redirect immediately, whether consent is needed or not is unclear, but the user will either have to login, or just redirected if they have a cookie and consent is also based on their circumstances.
I'll consent (no pun intended) that we can improve this diagram and make it easier to understand. I would suggest implementing a simple scenario first and seeing how it work before moving on to the more advanced scenario (by simple I mean every time a user need to log in as if it was their first time).
I'm trying to build an app that gets public information from Facebook. In the past, this type of operation would require an App Token (A token that could be used on behalf of the application to query public data). I had no problem implementing this technique with Twitter and Youtube, but Facebook looks like you can only access their API by letting a user login with Facebook via OAuth, retrieve them a personal token, and give them permission to query their own information.
I see a lot of posts related to this question, but they seem outdated. I know Facebook has been under a lot of privacy pressure lately and I'm wondering if they changed it.
Here are my questions:
Is it possible to generate an App Token used to access Facebook's Graph API?
If so, where can I find the documentation for this? I can only find information on using a user token.
I prefer to use Node.js as my backend, so any direction on where to start there would also be appreciated.
User Profiles: They always require a User Token, there is no way to access User Data without explicit authorization of the User, no matter if data is public or not.
Pages: If you manage the Page, you can use a Page Token of that Page to access data. If you want to access other Pages, you need to apply for Page Public Content Access - after that, you can use an App Token for those Pages.
In other words: App Tokens for public Pages (with PPCA), Page Tokens for Pages you own, User Tokens for User Profiles.
Btw, App Tokens do not need to be "generated", they are just "App-ID|App-Secret" (with a pipe in the middle).
So I noticed that apps like Tinder can show Instagram connect of lets say, User A on everyone else's phones even without requiring other users to actually sign into instagram.
For example: User-A connects instagram and gets access token. Users-B, C, D... can see A's public & private pictures without even logging into instagram.
Is there a way to view another user's instagram without requiring access token - even private pictures by just using CLIENT_ID?
Let's not make confusion. Tinder user can opt-in for sharing Instagram photos. Tinder has no worldwide access to Instagram photos. I will answer you from the security perspective, as I have never tried setting up a Tinder account with Instagram connection to test the scenario for you. Actually, from my understanding of Instagram APIs it could be impossible to get user's private pictures. But I could be wrong, so let me continue my discussion.
Access token is embedded in Tinder app code, you may find it or not if you decompile the code, according on the level of obfuscation, and almost certainly if you use software such as mitmproxy. I won't discuss such a practice here.
So Tinder client is granted a token to access user's pictures.
User opts in on Tinder/Instagram to access his private photos. A single access token is valid for pictures of all users that opted in to Instagram.If you steal Tinder's token you can access any Tinder-Instagram user's private photos. That is not bad. User has chosen to share private photos to the world. But if an Instagram user is not a Tinder user be sure that you won't get anything
Please mind that the token is valid for Tinder application, and is not user A's token. This is forbidden by security practices.
By associating your Tinder account with Instagram you grant Tinder's already-issued token to access your photos on behalf of you.
Summarizing:
Tinder client - Actor
Instagram - Resource server
User A's photos - Resource
User B (on Tinder, not on Instagram) - not an actor in the workflow
Token issued to Tinder: access to any (public or private??????) photos of users who have opted in to share Instagram photos on Tinder
Note: Tinder client may or may not use an Instagram-issued token. From a general security point-of-view, there are two implementation scenarios:
Tinder client contacts Instagram server with a token that is issued to Tinder application and encoded in all clients
PRO: bandwidth is charged to user only
CON: exposing the token may grant one to access any Tinder-Instagram user photos without passing by Tinder
Tinder app requests Tinder server to fetch photos from Instagram. Tinder client only authenticates with Tinder server
PRO: more secure design. Tinder-to-Instagram token never exposed. If a user leaves Tinder he can't access Instagram photos of other Tinder users
CON: Tinder server will be charged for the bandwidth needed to retrieve and distribute photos. This exposes Tinder to a potential violation of Instagram API ToS if they start caching the photos
The previous answer is way too confusing... so let's handle it in a easy way, according to your question.
Let's start from understanding, what is access_token, in their API, in API requests alike:
api.instagram.com/v1/users/self/media/recent/?access_token=%#
Working through API, receiving this access_token still requires granting of access, and Authentication (see the manual on Receiving an access_token). As you can read there, all the possible options still require authenticated access.
Even though our access tokens do not specify an expiration time, your app should handle the case that either the user revokes access, or Instagram expires the token after some period of time. If the token is no longer valid, API responses will contain an “error_type=OAuthAccessTokenError”. In this case you will need to re-authenticate the user to obtain a new valid token.
In other words: do not assume your access_token is valid forever.
This is standard authentication process in programming, with the access tokens, session identifiers, etc.
The world has been living with OAuth 2.0 Authorization Protocol for a long time, you are not the last guy who's concerned about it. If you are sleeping fine knowing about theoretical Session hijacking, then you shouldn't worry that much about potential security issues related to usage of APIs by access tokens.
It's secure enough. Aha, and another "small thing", I forgotten to mention: all requests to the Instagram API must be made over SSL (https:// not http://), which adds even more confidence.
To answer explicitly your question:
"is there a way to view another user's instagram without access token - even private pictures by just using CLIENT_ID?"
No, there's no possibility. Security token is the thing, which requires granting of access, and authentication. If it would allow this kind of access - this would be counted as security vulnerability. This is the basics of OAuth mechanism. If you need more understanding, you may read here, in a simple language, how OAuth is an authentication protocol works.
If you want a quick solution to the problem, I would avoid OAuth at all costs when dealing with public data. I would write a curl script to grab the public Instagram data from the user's profile URL, and parse the HTML server-side (or client-side).
Here's a quick mock-up example in PHP, using file_get_contents and DOMDocument:
//HTTP GET someone's profile (the easy way):
$html = file_get_contents('https://www.instagram.com/profile_xxxxxx/');
//Use PHP's built-in HTML parser
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->loadHTML($html);
$selector = new DOMXPath($doc);
//Instagram stores image URL's in meta tag "og:image"
foreach($selector->query('//attribute::*[contains(., \'og:image\')]') as $e) {
//Store profile photo from DOMNode $e
$photourl = $e->getAttribute('content');
//Grab profile photo
file_get_contents($photourl);
}
Let's consider that Instagram User Profiles pages like ISS page are available online without any authentication access:
https://www.instagram.com/iss/
Due to how Instagram works, only public images will be showed here (plus posts, followers, following).
So what you have to do is to get the page data. To do this you can use several solutions like PhantomJS that is as little as writing
var page = require('webpage').create();
page.open('https://www.instagram.com/iss/', function() {
var contents=page.contents; // here is the page contents
phantom.exit();
});
So, assumed you can execute this process on server-side you could provide those public profile images as a JSON object in a api response. Of course it's a little bit more complicated than this (i.e. you have to wait page resources to be loaded within PhantomJS, but at the end the web scraper can temporary save the page and turn it into a json structure, with <img/> source images, etc. ready to be showed in a app.
When I call an oauth provider like gmail and I get the token back, how can I make sure that all future calls I make are from that same client that did the authentication? that is, is there some kind of security token I should pass pack? Do I pass that token back everytime?
For example, if I have a simple data table used for a guest book with first,last,birthdate,id. How can I make sure that the user who "owns" that record is the only one who can update it. Also, how can I make sure that the only person who can see their own birthday is the person who auth'd in.
sorry for the confusing question, I'm having trouble understanding how azure mobile services (form an html client) is going to be secure in any way.
I recently tried to figure this out as well, and here's how I understand it (with maybe a little too much detail), using the canonical ToDoList application with server authentication enabled for Google:
When you outsource authentication to Google in this case, you're doing a standard OAuth 2.0 authorization code grant flow. You register your app with Google, get a client ID and secret, which you then register with AMS for your app. Fast forwarding to when you click "log in" on your HTML ToDoList app: AMS requests an authorization code on your app's behalf by providing info about it (client ID and secret), which ultimately results in a account chooser/login screen for Google. After you select the account and log in successfully, Google redirects to your AMS app's URL with the authorization code appended as a query string parameter. AMS then redeems this authorization code for an access token from Google on your application's behalf, creates a new user object (shown below), and returns this to your app:
"userId":"Google:11223344556677889900"
"authenticationToken":"eyJhbGciOiJb ... GjNzw"
These properties are returned after the Login function is called, wrapped in a User object. The authenticationToken can be used to make authenticated calls to AMS by appending it in the X-ZUMO-AUTH header of the request, at least until it expires.
In terms of security, all of the above happens under HTTPS, the token applies only to the currently signed-in user, and the token expires at a predetermined time (I don't know how long).
Addressing your theoretical example, if your table's permissions has been configured to only allow authenticated users, you can further lock things down by writing logic to store and check the userId property when displaying a birthday. See the reference docs for the User object for more info.