Login using facebook get username, email - javascript

I am using login using facebook in my website,
Here is the button
<fb:login-button scope="public_profile,email" onlogin="checkLoginState();">
</fb:login-button>
I am using the exact example given here
But after the check login status, i am getting the response with only the userid of facebook and token, but i want to get the username too.. How can i get that ?
Help pls
Here is the script
window.fbAsyncInit = function () {
FB.init({
appId: 'xxxx',
cookie: true, // enable cookies to allow the server to access
// the session
xfbml: true, // parse social plugins on this page
version: 'v2.2' // use version 2.2
});
FB.getLoginStatus(function (response) {
console.log(response);
console.log(response.email);
//here status is connected
//statusChangeCallback(response);
});
};
In the resopnse, i am getting the entire json,
In the response.status i am getting as connected
But while i try response.email i am getting undefined
How can i get the email or username ?

EDITED to show what actually fixed it for me:
So it does appear to depend on what version of the API your config is set to allow. BUT, I was able to get the email address on a v2.5 api by using the following:
If you are using the Hello World code, then replace this section:
FB.api('/me', function (response) {
console.log('Success ');
console.log(response);
});
With this:
FB.api('/me', { fields: 'email' }, function (response) {
console.log('Success ');
console.log(response);
});
The difference is adding the { fields: 'email' } object to the call. This appears to have been a new addition in either v2.4 or v2.5 of the API which is why older code you see on SO appears to work for the poster but not for you. Hope this helps.
I'm not sure this qualifies as a solution, but I was able to reproduce this issue (no email returned after a valid request).
I have two apps, each created under a different FB account. The first one was created more than a year ago and the second one was created today. I have code that runs perfectly against the older app (returns email) and fails against the newer app (no email).
At first I thought maybe FB just holds back on certain data for brand new apps but I thought it was odd that it wouldnt be documented anywhere.
So I decided to compare each app configuration side by side. I found that the older one had API VERSION (at the top of the dashboard) set to 2.0 and the newer was 2.5. The Hello World code on the API SDK page requests version 2.2 like so:
window.fbAsyncInit = function () {
FB.init({
appId: [my app id here],
cookie: true, // enable cookies to allow the server to access
// the session
xfbml: true, // parse social plugins on this page
version: 'v2.2'
})
};
According to the documentation, the fact that the newer app has API set to 2.5 in the config means that any requests for an older API (eg 2.2) will be automatically upgraded to 2.5. When I set the javascript above to request 2.5 (eg version: 'v2.5'), I was able to get the older app to fail too. So I suspect the issue is with the newer v2.5 api.
I have not been able to find out how to set my new app to accept older api calls but will update here if I do.

Related

Refreshing FB Access Token with Javascript SDK

For context I am trying to build a small microsite to pull social media insights from Facebook. I am looking to build a Django backend and React front end.
I would like to implement FB login with the Javascript SDK since according to the docs this refreshes the access token each time a FB call is made using the SDK.
I have a very simple login script taken from FB official docs which literally just logs in the user and then outputs the list of accounts the user has access to.
The issue is that, despite refreshing the page (and therefore performing an API request) the data expiration date doesn’t extend (it still displays the date of first login).
Is anyone familiar with the Javascript SDK and whether this is normal behaviour?
function statusChangeCallback(response) { // Called with the results from FB.getLoginStatus().
console.log(response);
if (response.status === 'connected') { // Logged into your webpage and Facebook.
testAPI();
FB.getAuthResponse(function(response){
console.log(response.authResponse.accessToken);
});
} else { // Not logged into your webpage or we are unable to tell.
document.getElementById('status').innerHTML = 'Please log ' +
'into this webpage.';
}
}
function checkLoginState() { // Called when a person is finished with the Login Button.
FB.getLoginStatus(function(response) { // See the onlogin handler
statusChangeCallback(response);
});
}
window.fbAsyncInit = function() {
FB.init({
appId : 'APP_ID_GOES_HERE',
cookie : true, // Enable cookies to allow the server to access the session.
xfbml : true, // Parse social plugins on this webpage.
version : 'v13.0' // Use this Graph API version for this call.
});
FB.getLoginStatus(function(response) { // Called after the JS SDK has been initialized.
statusChangeCallback(response); // Returns the login status.
});
};
function testAPI() { // Testing Graph API after login. See statusChangeCallback() for when this call is made.
console.log('Welcome! Fetching your information.... ');
FB.api('/me/accounts',
function(response) {
console.log(response)
});
}
function logout_js_user(){
FB.logout(function(response) {
// Person is now logged out
});
};
FB.getLoginStatus does refresh the Token, but not on every Page call. It only refreshes the Token when it is not valid anymore. That is why the expiration data does not change.
You can can a more accurate status with the second parameter of the function set to true, but be aware that this might affect performance:
FB.getLoginStatus(function(response) {
// this will be called when the roundtrip to Facebook has completed
}, true);
If you call FB.getLoginStatus on every page load, be careful not to
set this parameter for each as it will significantly increase the
number of requests to Facebook's servers, and thus decrease the
performance of your application.
Side note: ou can use FB.login to make the login less complicated (in my opinion) - here's an old but still valid article about that: https://www.devils-heaven.com/facebook-javascript-sdk-login/

Keycloak JavaScript API to get current logged in user

We plan to use keycloak to secure a bunch of web apps, some written in Java, some in JavaScript (with React).
After the user is logged in by keycloak, each of those web apps needs to retrieve the user that is logged in and the realm/client roles that the user has.
For Java apps, we tried the keycloak Java API (request -> KeycloakSecurityContext -> getIdToken -> getPreferredUsername/getOtherClaims). They seem to work fine
For JavaScript apps, we tried the following code, but could not get Keycloak to init successfully (Note this is in web app code after the user is already authenticated by keycloak, the app is only trying to retrieve who logged in with what roles):
var kc = Keycloak({
url: 'https://135.112.123.194:8666/auth',
realm: 'oneRealm',
clientId: 'main'
});
//this does not work as it can't find the keycloak.json file under WEB-INF
//var kc = Keycloak('./keycloak.json');
kc.init().success(function () {
console.log("kc.idToken.preferred_username: " + kc.idToken.preferred_username);
alert(JSON.stringify(kc.tokenParsed));
var authenticatedUser = kc.idTokenParsed.name;
console.log(authenticatedUser);
}).error(function () {
window.location.reload();
});
I assume it would be fairly common that web apps need to retrieve current user info. Anyone knows why the above code didn't work?
Thanks.
<script src="http://localhost:8080/auth/js/keycloak.js" type="text/javascript"></script>
<script type="text/javascript">
const keycloak = Keycloak({
"realm": "yourRealm",
"auth-server-url": "http://localhost:8080/auth",
"ssl-required": "external",
"resource": "yourRealm/keep it default",
"public-client": true,
"confidential-port": 0,
"url": 'http://localhost:8080/auth',
"clientId": 'yourClientId',
"enable-cors": true
});
const loadData = () => {
console.log(keycloak.subject);
if (keycloak.idToken) {
document.location.href = "?user="+keycloak.idTokenParsed.preferred_username;
console.log('IDToken');
console.log(keycloak.idTokenParsed.preferred_username);
console.log(keycloak.idTokenParsed.email);
console.log(keycloak.idTokenParsed.name);
console.log(keycloak.idTokenParsed.given_name);
console.log(keycloak.idTokenParsed.family_name);
} else {
keycloak.loadUserProfile(function() {
console.log('Account Service');
console.log(keycloak.profile.username);
console.log(keycloak.profile.email);
console.log(keycloak.profile.firstName + ' ' + keycloak.profile.lastName);
console.log(keycloak.profile.firstName);
console.log(keycloak.profile.lastName);
}, function() {
console.log('Failed to retrieve user details. Please enable claims or account role');
});
}
};
const loadFailure = () => {
console.log('Failed to load data. Check console log');
};
const reloadData = () => {
keycloak.updateToken(10)
.success(loadData)
.error(() => {
console.log('Failed to load data. User is logged out.');
});
}
keycloak.init({ onLoad: 'login-required' }).success(reloadData);
</script>
simple javascript client authentication no frameworks.
for people who are still looking...
Your code asks the Keycloak client library to initialize, but it doesn't perform a login of the user or a check if the user is already logged in.
Please see the manual for details: http://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter
What your probably want to do:
Add check-sso to the init to check if the user is logged in and to retrieve the credentials keycloak.init({ onLoad: 'check-sso' ... }). You might even use login-required.
Make sure that you register a separate client for the front-end. While the Java backend client is of type confidential (or bearer only), the JavaScript client is of type public.
You find a very minimal example here: https://github.com/ahus1/keycloak-dropwizard-integration/blob/master/keycloak-dropwizard-bearer/src/main/resources/assets/ajax/app.js
Alternatively you can register a callback for onAuthSuccess to be notified once the user information has been retrieved.
Once you use Keycloak in the front-end, you will soon want to look in bearer tokens when calling REST resources in the backend.
You might have solved the problem by this time. I hope this answer help rest of the people in trouble.
when you use JavaScript Adopter
Below javascript should be added in of html page.
<script src="http://localhost:8080/auth/js/keycloak.js"></script>
<script>
/* If the keycloak.json file is in a different location you can specify it:
Try adding file to application first, if you fail try the another method mentioned below. Both works perfectly.
var keycloak = Keycloak('http://localhost:8080/myapp/keycloak.json'); */
/* Else you can declare constructor manually */
var keycloak = Keycloak({
url: 'http://localhost:8080/auth',
realm: 'Internal_Projects',
clientId: 'payments'
});
keycloak.init({ onLoad: 'login-required' }).then(function(authenticated) {
alert(authenticated ? 'authenticated' : 'not authenticated');
}).catch(function() {
alert('failed to initialize');
});
function logout() {
//
keycloak.logout('http://auth-server/auth/realms/Internal_Projects/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri')
//alert("Logged Out");
}
</script>
https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter Reference Link.
Note : Read the comments for 2 methods of adding json credentials.

Public facebook page feed

I want to add last 4 news to my website, fetching them from facebook API. There is no facebook login on website or anything like that. I've created FB APP and used FB.api() function to fetch news, but APIs need access_token, which should not be seen publicly, but news fetching is on frontend (js). Is there a way to obtain some other access_token only for reading public news which can be public?
My code (which is working, just not safe)
window.fbAsyncInit = function() {
FB.init({
appId : 'my_app_id',
xfbml : true,
version : 'v2.8'
});
FB.api(
"https://graph.facebook.com/my_fb_page/feed?fields=full_picture,message,story,created_time&access_token=my_access_token",
function (response) {
if (response && !response.error) {
var news = response.data.splice(0,4);
console.log(news);
}
}
);
};
The proper way to do this is to use the Access Token server-side. Never use Tokens on the client, the App Access Token includes the App Secret - which is called "Secret" for a reason.
More information about Tokens:
https://developers.facebook.com/docs/facebook-login/access-tokens/
http://www.devils-heaven.com/facebook-access-tokens/

Localising Facebook Login using Javascript SDK

I am trying to localise the pop-up login box shown using FB.login() under the Javascript SDK but the dialog only displays in English. I use the code below to connect:
var facebookScript = "//connect.facebook.net/fr_FR/all.js"
$.ajaxSetup({ cache: true });
$.getScript(facebookScript, function () {
FB.init({
appId: SOCIAL_FACEBOOK_APP_ID,
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true // parse XFBML
});
FB.getLoginStatus(function () {
// At some point here FB.login() is called.
}, true);
});
I notice that if I take the URL of the login box and add &locale=fr_FR to it I get the desired result.
Facebook will automatically use the appropriate locale based on information from the users browser and account.
The localized versions of the SDK is mostly to make a few adaptions that need to happen on the third party site, mostly around left-to-right/right-to-left languages, and some labels.

Facebook login button with oauth 2 not calling auth.login

Our Asp.net site has been using the facebook login button (w/ javascript sdk) to handle the login process, and now that Oauth is mandatory (as of Dec 15, 2011 (yesterday))- it is broken. I've made some obvious changes that were mentioned the fb oauth migration blog, but still I'm getting errors. Specifically, when FB.init()'s parameter sets status=false, the auth.login event is never fired (which is a problem, because I use callback on that event to invoke another page which does some server-side open graph queries based on the authorization token in the resulting cookie). If I set status=true, then the event is fired, but the cookie is not set, and so I'm unable to make my server-side open graph queries.
Here's my javascript code (slightly edited...):
window.fbAsyncInit = function () {
FB.init({
appId: GetFacebookAppId(),
status: true,
cookie: true,
xfbml: true,
oauth: true
});
FB.Event.subscribe('auth.login', function (response) {
if (response.authResponse && response.authResponse.accessToken)
FacebookLoginRedirect();
});
}
Any ideas?
Thanks!
Try FB.getLoginStatus() instead of if (response.authResponse && response.authResponse.accessToken)
See detaild example here in the docs : ]
Hopefully someone finds this useful- I was able to listen to a different event: auth.statusChange, check the response, and then proceed. One thing was that I had to unsubscribe to this event once I had successfully logged in, but then it seemed to work ok.
listen to auth.statusChange :
FB.Event.subscribe('auth.statusChange', handleStatusChange);

Categories

Resources