I'm writing an app which provide service for clients to schedule their status updates into twitter.
So a client authorizes on my web page (with twitter OAuth), creates list of deferred statuses, set times, possibly logout.
When it is time for my service to post these updates - there is a problem: I cannot obtain access_token, because my user has already logged-out and may be not here at all and therefore cannot grant access to the app.
There are few different options to obtain the access token, is anyone can explain me which the best choice for me.
Options: https://dev.twitter.com/docs/auth/obtaining-access-tokens
You want to use 3-legged.
When the user OAuths, your site will be sent their OAuth token. You need to store it in a database and then use it when it is time to post the status.
The token will remain valid even if the user has logged out.
Related
I'm writing an app that needs to periodically get reports and update campaigns for a few users. The app can access their accounts now when they login and authorize, but what I want/need is for oauth to give access to the app to access their accounts whenever the script has to run. Is this possible?
Yes, it's possible. The relevant documentation is here.
You need to add access_type=offline to your request for an authorization code. The user will then be prompted to grant offline access to your script in the consent screen, and once he accepts, the response to your app will include a refresh token. Refresh tokens don't expire and can be used to generate new access tokens.
Note that if you lose a refresh token, you'll need to request authorization from your use again, this can be done by including prompt=consent in the request.
I am writing an application which will connect to multiple email servers using OAuth. As part of initial connection establishment, user will be prompted to give access to application. After granting access, it will redirect to the url provided while registering the application in OAuth API.
Now i want to identify for which user the access token and refresh token belongs after redirect url comes to my application. I want to treat all requests happening in one user session as unique. Can someone help me.
I'm not 100% sure I followed your question, but my understanding is that you want to determine some of the information about the user that's just logged into your API client. You can get email addresses by requesting the https://www.googleapis.com/auth/userinfo.email scope and running a oauth2/userinfo GET request:
gapi.client.oauth2.userinfo.get().execute(function(resp,raw)...
Depending on which scopes you have access too, you will also get a display name and some other info. Best bet is just to console.log(resp) and pick out what you want to use.
I'm building an iOS app that will use instagram photos in a slide show as the background of the app.
What I want to do is just set up a specific account that I can upload pictures to, and then the app will pull in the most recent photos from this account.
So far, I've set up the account and have been able to generate an access token manually by inserting my client id and redirect URI into this URL
https://instagram.com/oauth/authorize/?client_id=[CLIENT_ID]&redirect_uri=[REDIRECT_URI]&response_type=code
However, I've read that the access token generated from following this procedure is not permanent. I do not want the users of my app to ever see the authentication going on in the background. They themselves will never actually login into Instagram.
What would be the best way of making sure my app is always authenticated at launch and that the access token is always valid?
Thanks
A typical OAuth flow has the resource owner (a user) approve or deny requests from a client application. When you first got an access token, you had to complete a form approving access to Intsagram by your app.
Since you want to hide the auth_server/resource_owner interaction from your end users, you'll have to automate the role of the resource owner. The access token should tell you when it expires. Since it's your redirection endpoint that has the access token, that's where you'll need code to detect the token will soon expire and request a new one. Your code will need to
Simulate a request from the client app by going to https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code
Respond to the HTML page that is returned. Approve the request.
The server will respond with an authorization code that you can exchange for
a new access token.
There are some hoops to jump through because OAuth is designed for the resource owner to approve or deny each request.
I don't think you would want to do this by logging into the target account because having your app's user log in to Instagram as the account you are talking about may be unnecessary.
While I am not an expert on the Instagram API, it looks like you can avoid using an access token for getting the feed of a particular user.
Here is some support for this:
Do you need to authenticate?
For the most part, Instagram’s API only requires the use of a client_id. A client_id simply associates your server, script, or program with a specific application. However, some requests require authentication - specifically requests made on behalf of a user. Authenticated requests require an access_token. These tokens are unique to a user and should be stored securely. Access tokens may expire at any time in the future.
http://instagram.com/developer/authentication/
If a client ID is only associated with your application and does not require the user to authenticate, it appears that this endpoint should work:
GET /users/user-id/media/recent
https://api.instagram.com/v1/users/3/media/recent/?client_id=YOUR-CLIENT_ID
The functionality is the same with the previous one, but use client_id
instead of access_token
PARAMETERS
COUNT Count of media to return.
MAX_TIMESTAMP Return media before this UNIX timestamp.
MIN_TIMESTAMP Return media after this UNIX timestamp.
MIN_ID Return media later than this min_id. CLIENT_ID A valid client id.
MAX_ID Return media earlier than this max_id.
http://instagram.com/developer/endpoints/users/#get_users_media_recent_with_client_id
Facebook's deprecation of the offline_access permission is coming May 2012 and the documentation isn't giving us enough information on how to handle it.
We have an iOS app and corresponding service that powers it and integrates with Facebook in a deep way to leverage a user's friend list within out app (so if your FB friends are also using the app you can more easily connect). This is like how all social apps seem to work, so nothing special here.
Client
Our app uses Facebook iOS SDK to allow user to login, which we currently ask for offline_access. The token is persisted in our iOS app, but also sent to our server where it is saved. The client acts on behalf of user to post updates to a user's newsfeed (we also ask for publish_stream permission).
Server
Our server periodically checks to see if user's FB friends are now using our app. Next time user signs in, we expose content and relationships in a certain way to promote that user's friends. The server also acts on behalf of the user to periodically connect to the graph API and get the user's current friends list. This is so we can account for changes in a user's relationships and have them reflected in our app. We do this when the user isn't currently using the app so they have the best experience the next time they do use it. To enable this, our iOS app sends the access token to our server which it uses and why we ask for offline_access.
Note: If user signs out of our app explicitly, we delete the access tokens from both client and server.
Problems
Now that there is no longer a perpetual access token we can use, I'm trying to figure out the best practice for still enabling our scenarios while leveraging facebook's new intended way of handling and extending access tokens. The documentation is unfortunately not totally helpful.
Questions
A. When you authenticate through the newest Facebook iOS SDK, what is the default lifetime of the access token you get? This document says an extended token request will give you one that lasts 60 days. This other document talks about the first access token request and mentions varying validities but it's unclear and does it talk about specific validity times:
(emphasis is mine)
When you obtain an access token from Facebook, it will be valid
immediately and usable in requests to the API for some time period
defined by Facebook. After that period has elapsed, the access token
is considered to have expired and the user will need to be
authenticated again in order for your app to obtain a fresh access
token. The duration for which a given access token is valid depends on
how it was generated.
There are also events which may cause an access token to become
invalid before its expected expiry time. Such events include the user
changing their password, an application refreshing it's App Secret.
Dealing with varying access token expiry times, and handling the case
when an access token becomes invalid before its expected expiry time
is essential for building robust social experiences.
B. For the client, now that the access token isn't necessarily long lived, is the right approach for us to:
Let use login through FB, then detect whenever the access token is expired. If it is, then call into FB iOS SDK to re-authentication/re-authorize? (this should just trigger user to bounce out to FB iOS app, and in most cases come immediately back to our app with a new access token).
C. According to this blog post I found, you can only extend an access token once:
Can I exchange my 60 day access token for a new 60 day access token?
No, sorry you cannot. You can only exchange a valid (meaning current)
user access token for an extended one. You cannot extend an already
extended access token.
On the client, I can just handle this by prompting a re-authentication/re-authorization as I mentioned in Question B. However, this doesn't work on our server. We could certainly have the server renew it once to 60 days, but what happens on the 61st day? The server just stops being able to sync the friend's list?
D. It seems to make sense to check the validity of the FB access token every time the app starts or re-hydrates from sleep. What is the best way for our iOS app to check this? Is there a recommended endpoint to call to validate a token? Should we just call into https://graph.facebook.com/me passing the access token and checking the response?
Note: we can certainly record the expires time when we get the initially extended token, but this isn't reliable since the user could revoke our app's permission anytime which makes the expires time an unreliable data point on validity
Overview
I believe that the root of what facebook is trying to achieve is to prevent an app from having perpetual ever-lasting access to a user's account. So, with the new migration an app can only access an account for 60 days unless the user signs in again.
I don't work for facebook, but here are my findings from playing around with the facebook graph api.
General Solution
Whenever a user signs in, take their access token and immediately extend/refresh it, and save it
Record the expiration date of the access token
When an access token expires (either from the recorded date, or a graph API exception telling you so), then notify the user that you don't have access, and ask them to sign in again.
Answers
A. When you authenticate through the newest Facebook iOS SDK, what is the default lifetime of the access token you get? This document says an extended token request will give you one that lasts 60 days. This other document talks about the first access token request and mentions varying validities but it's unclear and does it talk about specific validity times:
Here's how it works:
The first sign-in grants you approximately two hours
By refreshing the access token, you can get up to 60 days
If the user doesn't sign in to those 60 days, there is no way to get access for longer without having them sign in.
If the user de-authorizes your app, that 60 day windows ends immediately, and you will no longer have access.
B. For the client, now that the access token isn't necessarily long lived, is the right approach for us to: Let use login through FB, then detect whenever the access token is expired. If it is, then call into FB iOS SDK to re-authentication/re-authorize? (this should just trigger user to bounce out to FB iOS app, and in most cases come immediately back to our app with a new access token).
If the users access token is expired, your only option is to have them go through a login loop like you are talking about.
C. According to this blog post I found, you can only extend an access token once. On the client, I can just handle this by prompting a re-authentication/re-authorization as I mentioned in Question B. However, this doesn't work on our server. We could certainly have the server renew it once to 60 days, but what happens on the 61st day? The server just stops being able to sync the friend's list?
You can only extend an access token once. On the 61st day, you are out of luck. Best notify the user and let them know that unless they sign in, you won't be able to do anything.
D. It seems to make sense to check the validity of the FB access token every time the app starts or re-hydrates from sleep. What is the best way for our iOS app to check this? Is there a recommended endpoint to call to validate a token? Should we just call into https://graph.facebook.com/me passing the access token and checking the response?
I haven't be able to find an API equivalent of the Debug Console. This FB blog article talks about invalidated access tokens, but doesn't mention any API methods in particular meant to test the API.
I your suggestion of hitting https://graph.facebook.com/me would work just fine is exactly what they recommend in their example. In fact, I might use this approach in my app as a pro-active way of checking an access token.
Tid Bits
When you "refresh" an access token, a new access token will be returned. The response looks like: access_token=TOKEN&expires=5183912
You can only "refresh" an access token once. If you try to "refresh" the long-lived token returned from a previous call, it will return the same token, but doesn't throw an exception unless the token has expired. (in other words, you can safely try to refresh your token)
The default access token length seems to be around 2 hours
If you "refresh" an access token, that new access tokens seems to be the one that you'll get from the facebook API afterwards (instead of returning the original, short-lived access token)
Also, if you want to play around, these tools make it easy to test out your use case in a browser before burying it in your code:
Graph API Explorer - For creating and getting access tokens
Debug Console - For checking the expiry date of tokens before/after refresh
Refresh Endpoint - For manually testing extending your tokens
Great answer, one important addition : the default token lasts between 1 and 2 hours. You get the remaining of the hour during which the user signs up, plus 1 full hour. For example if a user signs up at 3:45pm, the access token will expire at 5pm. To be safe developers should assume it only lasts 1hour.
I have a Twitter web app that allows users to submit tweets from my site. However they have to re-login every time they submit a new tweet. Is there a way to save the OAuth session and don't prompt the login screen until users clear their browser cache?
When you get the callback from Twitter after the user has validated you, you'll receive an auth_token in the headers of the request; you're meant to cache that token, and supply it every time the user makes a request.
It sounds like you're not caching that token and supplying it when the user makes a request.
You need to store the oauth_token, you can use the same for all requests.
On the FAQ of Twitter API
How long does an access token last?
We do not currently expire access
tokens. Your access token will be
invalid if a user explicitly rejects
your application from their settings
or if a Twitter admin suspends your
application. If your application is
suspended there will be a note on your
application page saying that it has
been suspended.
you need a db tables called user and user_tokens. Inside the user you have: id, user_oauth_secret, user_oauth_token. Inside the the user_token you need this columns: id, user_id, token, created, expires. make sure this token is unique (and long) with some random hash. now you can save this token to the user's cookie and find the right oauth data later.
You need to store two tokens.
When you make the OAuth request the first time, it will show the Twitter auth screen. After auth, your OAuth callback page will get two query string parameters, "oauth_token" and "oauth_token_secret" for the user. You need to store these (probably in a database) somewhere.
Then, when you request OAuth permission again from Twitter, send the two tokens, and the user will automatically be authorized.
You shouldn't have to code this yourself. There are plenty of OAuth libraries out there.
You have to maintain a long session with the user and save the access tokens. Cookies are commonly used to recognize users.