Recuperando foto do Facebook usando passaporte-facebook
-
21-12-2019 - |
Pergunta
Consigo recuperar informações básicas do usuário via passaporte-facebook, seguindo o código abaixo e salvando no mongodb:
app.get("/auth/facebook", passport.authenticate("facebook", { scope : ["email", "publish_stream", "user_location", "user_hometown", "user_birthday", "read_friendlists"]}));
app.get("/auth/facebook/callback", passport.authenticate("facebook",{ successRedirect: '/', failureRedirect: '/'}));
var mongoose = require('mongoose'),
FacebookStrategy = require('passport-facebook').Strategy,
Users = mongoose.model('Users');
module.exports = function (passport, config) {
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
Users.findOne({ _id: id }, function (err, user) {
done(err, user);
});
});
passport.use(new FacebookStrategy({
clientID: config.facebook.clientID,
clientSecret: config.facebook.clientSecret,
callbackURL: config.facebook.callbackURL
}, function(accessToken, refreshToken, profile, done) {
Users.findOrCreateFaceBookUser(profile, done);
}));};
Porém, não consigo ver a foto do perfil no "perfil".
A documentação https://github.com/jaredhanson/passport-facebook diz que para recuperar fotos precisamos passar os profileFields conforme abaixo.Mas, ao fazer isso, consigo ver o URL da foto, mas perco outros dados que estavam contidos em _json, por exemplo.perfil._json.localização.nome.Como posso recuperar fotos com outras informações do usuário intactas?
passport.use(new FacebookStrategy({
// clientID, clientSecret and callbackURL
profileFields: ['id', 'displayName', 'photos', ....]},// verify callback));
Solução 3
Sim, a imagem pode ser acessada através da API gráfica usando o token de acesso como este."graph.facebook.com/";+ profile.username + "/imagem" + "?width=200&height=200" + "&access_token=" + accessToken;Não há necessidade de usar os campos do perfil.
Outras dicas
Se você precisar de uma imagem maior (o padrão no exemplo do miksii acima é 50px x 50px, que é bem pequeno), use:
profileFields: ['id', 'displayName', 'name', 'gender', 'picture.type(large)']
e então
picture: profile.photos ? profile.photos[0].value : '/img/faces/unknown-user-pic.jpg'
Isso retornará uma imagem de perfil de 200px x 200px para esse usuário.
Além de responder à sua pergunta - você não precisa fazer dessa maneira.Como você mencionou, você pode definir os atributos obrigatórios para o perfil do Facebook:
clientID: "...",
clientSecret: "...",
callbackURL: "...",
profileFields: ['id', 'displayName', 'name', 'gender', ..., 'photos']
O que você pode fazer é simplesmente pegar o valor do atributo fornecido.Digamos que você queira criar um atributo que contenha este valor:
picture: profile.photos ? profile.photos[0].value : '/img/faces/unknown-user-pic.jpg'
Esta provou ser uma solução melhor, pois alguns usuários ou às vezes o valor do nome de usuário podem ser indefinidos.
Espero que você também ache isso útil,
Obrigado.
Como isso responder, funcionará melhor com este código.
passport.use(new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: FACEBOOK_APP_CALLBACK,
profileFields: ['id', 'displayName', 'picture.type(large)', 'email', 'birthday', 'friends', 'first_name', 'last_name', 'middle_name', 'gender', 'link']
}, (accessToken, refreshToken, profile, cb) => {
const picture = `https://graph.facebook.com/${profile.id}/picture?width=200&height=200&access_token=${accessToken}`
//
}))