The fb access token always get expired in ember app - facebook-graph-api

I am using ember-simple-auth and ember-cli-facebook-js-sdk.I am using the ember-cli-facebook-sdk because I want to get the user photo anytime as facebook only give the access which expires in 60 mins.So I can't save also.Ember-cli-facebook-sdk is working fine.But sometimes I am getting an error in my network console.
{"error":{"message":"An active access token must be used to query information about the current user.","type":"OAuthException"}
I am not able to think why this error is coming.I have a initializer which have facebook id and api version.And Now I am using Fb.api and others in my controller,component and other.But it fails sometimes.Please anwser where I am going wrong.Thanks in advance.
initializer/fb.js
import FB from 'ember-cli-facebook-js-sdk/fb';
export default {
name: 'fb',
initialize: function() {
return FB.init({
appId: '1234567',
version: 'v2.3',
xfbml: true
});
}
};
controller.js
usrphoto:Ember.computed('model',function(){
var currentState = this;
FB.api('/me/picture','Get',{'type':'large'}).then(function(response) {
currentState.set('usrphoto', response.data.url)
})
}

I think what happens here is, that your Facebook session expires. In that case you need to handle the error and manage it. For example, you could check for a valid session and in case the session is expired, require a new token and then do your request:
FB.getLoginStatus().then(function(response) {
if (response.status === 'connected') {
return Ember.RSVP.resolve();
} else {
return FB.login('email,user_photos'); //set your scope as needed here
}
}).then(function() {
return FB.api('/me/picture','Get',{'type':'large'});
}).then(function(response) {
currentState.set('usrphoto', response.data.url);
});
Another possibility is to handle the error in the catch of the FB.api:
FB.api('/me/picture','Get',{'type':'large'}).then(function(response) {
currentStatte.set('userphoto', response.data.url);
}).catch(function(reason) {
...handle your error here...
});

Related

ember-simple-auth is not saving auth response to session

I'm using ember-simple-auth and I can see that the authentication token is returned and that my custom authenticator is putting it (code-wise) into the session.
I can use wireshark to see that the token comes back but I can't debug into the authenticator code - I can't even use debug statements as the redirect wipes the network session on google chrome.
However, it isn't in the session (google chrome tools) and the session isn't considered authenticated.
Why is the lock code correctly popping up the auth0 dialog but not saving the session? I don't really think it is something with this code but rather a config or initialization setting I'm unaware of.
I expect the session to be saved in the _setupFutureEvents as the first thing it does.
Any ideas what I can try to get it to work?
(/app/authenticators/lock.js) authenticate (options) {
return new Ember.RSVP.Promise((res) => {
this.get('lock').show(options, (err, profile, jwt, accessToken, state, refreshToken) => {
if (err) {
this.onAuthError(err);
} else {
var sessionData = { profile, jwt, accessToken, refreshToken };
// pass the NEW auth0 session data into future events
this.afterAuth(sessionData).then(response => res(this._setupFutureEvents(response)));
}
});
});
},
afterAuth (data) {
return Ember.RSVP.resolve(data);
},
_setupFutureEvents (data) {
// set the session info here
this.get('sessionData').setProperties(data);
this._clearJobs();
this._scheduleExpire();
if (this.get('hasRefreshToken')) {
this._scheduleRefresh();
}
return this.get('sessionData');
},

Ember Simple Auth immediately invalidates the session after authenticating with Torii

I am trying to set up Torii with my own OAuth flow and Ember-Simple-Auth. I can get a successful authentication event, but immediately after I authenticate, the invalidateSession trigger is fired causing my session to end. I can see this by intercepting sessionInvalidated() in /app/routes/application.js (which has the ApplicationRouteMixin).
Have any of you come across this? Is there something peculiar that would cause an immediate session validation? Any advice would be greatly appreciated.
EDIT: I think it has to do with the torii popup code because the first return works, but the second doesn't. Any thoughts?
import OAuth2 from 'torii/providers/oauth2-code';
import {configurable} from 'torii/configuration';
export default OAuth2.extend({
name: 'api',
init() { this.set('clientID', this.get('apiKey')); },
baseUrl: configurable('baseUrl'),
redirectUri: configurable('redirectUri'),
responseParams: ['access_token', 'user_id', 'first_name'],
requiredUrlParams: ['client_id', 'redirect_uri', 'response_type'],
open() {
let name = this.get('name');
let url = this.buildUrl();
let redirectUri = this.get('redirectUri');
let responseParams = this.get('responseParams');
// this return works
return { 'yes' : 'no' }
// this return causes the immediate invalidation
return this.get('popup').open(url, responseParams).then((authData) => {
var missingResponseParams = [];
responseParams.forEach(function(param){
if (authData[param] === undefined) {
missingResponseParams.push(param);
}
});
if (missingResponseParams.length){
throw new Error("The response from the provider is missing " +
"these required response params: " + missingResponseParams.join(', '));
}
return {
access_token: authData.access_token,
first_name: authData.first_name,
user_id: authData.user_id,
provider: name,
redirectUri: redirectUri
};
});
}
});
the real answer is using this fork: https://github.com/simplabs/ember-simple-auth/pull/931 (hopefully it'll be in master soon).
You might have this.get('session').invalidate(); somewhere. Probably in one of your controllers action properties. You would usually put that in your actions for your logout button. Maybe you copy and pasted it by accident. If you post some code I might be able to look at it some more

How to client side authentication with Emberjs

First of all I don't use Ruby nor Devise :) (all my searches led me to plugins that kind of rely on Devise)
I want to do pretty simple authentication with Ember, I have a REST backend that blocks requests without a proper cookie(user-pass) and i want Ember to watch when it gets 403 forbidden (won't let you to transition into protected URLs) and then pop up a user-login dialog.
So when a user tries to send a new message for example(lets say i've built a forum) Ember will fire the request and if it gets 403 it will block the transition and popup a login form and will retry the transition after the login have completed
Also is there a way to get the errors from ember-data and respond to them? (if a user tries to change an attribute he can't access i would like to inform him about it[Access denied or something like that])
I want to use custom errors that my server will send to ember data not just error numbers but words like "Sorry you can't change this before 12 PM"
You can simply listen to the response of your server and transition to your LOGIN (or whatever you call it) route. In my apps I happen to keep two types of routes (LOGIN and AUTHENTICATED). When they access the authenticated routes without logging in, they get a 401 unauthorized error and get transitioned to the LOGIN route.
// AuthenticatedRoute.js
redirectToLogin: function(transition) {
// alert('You must log in!');
var loginController = this.controllerFor('login');
loginController.set('attemptedTransition', transition);
this.transitionTo('login');
},
events: {
error: function(reason, transition) {
if (reason.status === 401) {
this.redirectToLogin(transition);
} else {
console.log(reason);
window.alert('Something went wrong');
}
}
},
model: function () {
return this.store.find('post');
},
So now when the user requests for post he gets a 401 and gets transitioned to LOGIN controller.
// LoginController.js
login: function() {
var self = this, data = this.getProperties('username', 'password');
// Clear out any error messages.
this.set('errorMessage', null);
$.post('/login', data).then(function(response) {
self.set('errorMessage', response.message);
if (response.success) {
alert('Login succeeded!');
// Redirecting to the actual route the user tried to access
var attemptedTransition = self.get('attemptedTransition');
if (attemptedTransition) {
attemptedTransition.retry();
self.set('attemptedTransition', null);
} else {
// Redirect to 'defaultRoute' by default.
self.transitionToRoute('defaultRoute');
}
}
});
}
The basic answer you need is capturing the events in the route and transitioning accordingly. I just happened to include the code for attempted transition as it comes in handy at times.

facebook javascript permission dialog for email

i have a question.... i am actually developing a facebook application with FB javascript SDK. In my application I need email permission for further processing. i am using
FB.Connect.showPermissionDialog("email");
but some how the dialog doesn't appears... here is my code
<script>
appid = '*************';
name = 'Palmchip Test App';
href = 'https://apps.facebook.com/*********/';
FB.init({
appId:appid, cookie:true,
status:true, xfbml:true
});
FB.getLoginStatus(function(response) {
if (response.session) {
alert("You are logged in...");
FB.Connect.showPermissionDialog("email", function(perms) {
if (!perms) {
alert("no access");
} else {
alert("accessed...");
}
});
}
else {
top.location.href='https://graph.facebook.com/oauth/authorize?client_id='+appid+'&redirect_uri='+href+'&display=page';
}
});
</script>
the alert which says you are logged in... works fine but then nothing happens .....
You need to upgrade to OAuth 2.0 ouath: true
You should use the new OAuth Dialog
You should be aware when upgrading that FB.getLoginStatus() will return different objects: response.authResponse
Try this code block
FB.init({appId: <?= APP_ID ?>, status: true, cookie: true, xfbml: true, oauth:true});
function getin(){
FB.login(function(response) {
if (response.authResponse) {
var regurl = "/login";
location.href=regurl;
} else {
var regurl = "/logout";
window.location.href=regurl;
}
}, {scope:'email'});
}
So when you call the getin() function , if the current user already gave you the email address it'll do nothing for him just will redirect him to /login url , but if the user is a new user then he/she will see a pop-up box asking for the email address once he/she allows that you can pull the email address using graph or fql. BTW response inside FB.login has the user id , access_toke and some more useful data so save that for further use.

pages.isFan returns incorrect signature

I am working on a Facebook canvas iFrame application, and I`m going insane.
I am trying to check if a user is a fan of the page where the app is located, so that I can allow or disallow voting.
I use the following code:
function CheckFan() {
FB.init({
appId: 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true // parse XFBML
});
FB.api({ method: 'pages.isFan', page_id: '145116742177104' }
, function(resp) {
if (resp) { $('#main_frame').show(); $('#non_fan').hide(); }
else { $('#main_frame').hide(); $('#non_fan').show(); }
});
}
This JS SDK is driving me up the wall, while calling the documentation "incomplete" is an insult to incompleteness.
Any input will be appriciated.
Thank you!
-Elad
This has been deprecated by Facebook.
A new Graph API alternative will hopfuly be available by the time we need to deploy the app.
For now I use FQL:
FB.api({ method: 'fql.query', query: 'SELECT uid FROM page_fan WHERE uid= ' + user_id + ' AND page_id=145116742177104' },
function(result) {
if (result.length)
{ $('.main_frame').show(); $('#non_fan').hide(); } else { $('.main_frame').hide(); $('#non_fan').show(); }
});