La guía o código que hallarás en este post es la solución más eficiente y válida que hallamos a tus dudas o dilema.
Solución:
He descubierto cómo modificar el tutorial de Facebook para la API de inicio de sesión con ReactJS. Espero que esto ayude a cualquiera que esté luchando con esto.
En primer lugar, en el componente de reacción donde desea el enlace de inicio de sesión, incluya este código:
componentDidMount: function()
window.fbAsyncInit = function()
FB.init(
appId : '',
cookie : true, // enable cookies to allow the server to access
// the session
xfbml : true, // parse social plugins on this page
version : 'v2.1' // use version 2.1
);
// Now that we've initialized the JavaScript SDK, we call
// FB.getLoginStatus(). This function gets the state of the
// person visiting this page and can return one of three states to
// the callback you provide. They can be:
//
// 1. Logged into your app ('connected')
// 2. Logged into Facebook, but not your app ('not_authorized')
// 3. Not logged into Facebook and can't tell if they are logged into
// your app or not.
//
// These three cases are handled in the callback function.
FB.getLoginStatus(function(response)
this.statusChangeCallback(response);
.bind(this));
.bind(this);
// Load the SDK asynchronously
(function(d, s, id)
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
(document, 'script', 'facebook-jssdk'));
,
// Here we run a very simple test of the Graph API after login is
// successful. See statusChangeCallback() for when this call is made.
testAPI: function()
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response)
console.log('Successful login for: ' + response.name);
document.getElementById('status').innerHTML =
'Thanks for logging in, ' + response.name + '!';
);
,
// This is called with the results from from FB.getLoginStatus().
statusChangeCallback: function(response)
console.log('statusChangeCallback');
console.log(response);
// The response object is returned with a status field that lets the
// app know the current login status of the person.
// Full docs on the response object can be found in the documentation
// for FB.getLoginStatus().
if (response.status === 'connected')
// Logged into your app and Facebook.
this.testAPI();
else if (response.status === 'not_authorized')
// The person is logged into Facebook, but not your app.
document.getElementById('status').innerHTML = 'Please log ' +
'into this app.';
else
// The person is not logged into Facebook, so we're not sure if
// they are logged into this app or not.
document.getElementById('status').innerHTML = 'Please log ' +
'into Facebook.';
,
// This function is called when someone finishes with the Login
// Button. See the onlogin handler attached to it in the sample
// code below.
checkLoginState: function()
FB.getLoginStatus(function(response)
this.statusChangeCallback(response);
.bind(this));
,
handleClick: function()
FB.login(this.checkLoginState());
,
Luego, en su método de renderizado, asegúrese de tener algo de HTML que llame a ese handleClick:
Login
Tenga en cuenta que este es el mismo código del tutorial, pero colocado en un componente ReactJS. La única diferencia es que debe vincular esto estratégicamente para que las funciones de la API de Facebook formen parte de su componente de reacción. Este inicio de sesión terminará con un mensaje de respuesta analizado a partir de la respuesta dada por FB.getLoginStatus (). También puede sacar el token de ese objeto de respuesta y enviarlo a su backend para autenticación con algo como passport-facebook-token.
Usé Promesas para el flujo de autenticación de Facebook
mixins / facebook.js
const promises =
init: () =>
return new Promise((resolve, reject) =>
if (typeof FB !== 'undefined')
resolve();
else
window.fbAsyncInit = () =>
FB.init(
appId : '',
cookie : true,
xfbml : true,
version : 'v2.5'
);
resolve();
;
(function(d, s, id)
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
(document, 'script', 'facebook-jssdk'));
);
,
checkLoginState: () =>
return new Promise((resolve, reject) =>
FB.getLoginStatus((response) =>
response.status === 'connected' ? resolve(response) : reject(response);
);
);
,
login: () =>
return new Promise((resolve, reject) =>
FB.login((response) =>
response.status === 'connected' ? resolve(response) : reject(response);
);
);
,
logout: () =>
return new Promise((resolve, reject) =>
FB.logout((response) =>
response.authResponse ? resolve(response) : reject(response);
);
);
,
fetch: () =>
return new Promise((resolve, reject) =>
FB.api(
'/me',
fields: 'first_name, last_name, gender',
response => response.error ? reject(response) : resolve(response)
);
);
export const Facebook =
doLogin()
this.setState(
loading: true
, () =>
promises.init()
.then(
promises.checkLoginState,
error => throw error;
)
.then(
response => this.setState(status: response.status); ,
promises.login
)
.then(
promises.fetch,
error => throw error;
)
.then(
response => this.setState(loading: false, data: response, status: 'connected'); ,
error => throw error;
)
.catch((error) =>
this.setState(loading: false, data: , status: 'unknown');
console.warn(error);
);
);
,
doLogout()
this.setState(
loading: true
, () =>
promises.init()
.then(
promises.checkLoginState,
error => throw error;
)
.then(
promises.logout,
error => this.setState(data: , status: 'unknown');
)
.then(
response => this.setState(loading: false, data: , status: 'unknown'); ,
error => throw error;
)
.catch(error =>
this.setState(loading: false, data: , status: 'unknown');
console.warn(error);
);
);
,
checkStatus()
this.setState(
loading: true
, () =>
promises.init()
.then(
promises.checkLoginState,
error => throw error;
)
.then(
response => this.setState(status: response.status); ,
error => throw error;
)
.then(
promises.fetchUser,
error => throw error;
)
.then(
response => this.setState(loading: false, data: response, status: 'connected'); ,
error => throw error;
)
.catch((error) =>
this.setState(loading: false, data: , status: 'unknown');
console.warn(error);
);
);
;
Profile.jsx
import Facebook from './mixins/Facebook.js';
import Button from 'react-bootstrap';
const ProfileHandler = React.createClass(
mixins: [Facebook],
componentDidMount()
this.checkStatus();
,
getInitialState()
return
status: 'unknown',
loading: false,
data:
;
,
render()
const loading = this.state.loading ? Please wait, profile is loading ...
: null;
const message = this.state.status === 'connected'
? (
Hi data.name!
)
: ();
return (
message
loading
);
);
ritmatter dio una buena respuesta, pero mostraré cómo hice esto de manera un poco diferente. Quería usar el botón de inicio de sesión de Facebook en lugar del mío para activar la devolución de llamada para verificar el estado de inicio de sesión. El botón de inicio de sesión podría verse así:
El botón tiene un inicio de sesión attribute, que el analizador jsx no admite. El uso de data-onlogin en la forma de reacción no funcionaba, así que acabo de agregar el botón en componentDidMount:
componentWillMount: function ()
window['statusChangeCallback'] = this.statusChangeCallback;
window['checkLoginState'] = this.checkLoginState;
,
componentDidMount: function ()
var s = '';
var div = document.getElementById('social-login-button-facebook')
div.innerHTML = s;
,
componentWillUnmount: function ()
delete window['statusChangeCallback'];
delete window['checkLoginState'];
,
statusChangeCallback: function(response)
console.log(response);
,
// Callback for Facebook login button
checkLoginState: function()
console.log('checking login state...');
FB.getLoginStatus(function(response)
statusChangeCallback(response);
);
,
render: function()
return (
);
Todo lo que queda por hacer es activar el botón al montar el componente si desea llamar automáticamente a checkLoginState.