Closed elmeerr closed 8 years ago
Can you try wording your question differently? I don't quite understand what you're asking.
@Awk34 sorry...let me try again:
when I'm using facebook login, when I don't have an account on the system, I need to connect to facebook to create a new account, so...after that, the callback redirects to initial page. In that point, it should redirect with user information, this way, on route router.get('/me', auth.isAuthenticated(), controller.me);
it won't get error 401
instead of this, I'm being redirected to login page (because of error 401)...and I need to connect to faceebok again and only then get all the user information.
I don't undestand why I can't get user information right after create the account. (you could look the code I already posted to see if I'm missing something)
I don't know if it's relevant but this part
if (req.query && req.query.hasOwnProperty('access_token')) {
req.headers.authorization = 'Bearer ' + req.query.access_token;
}
is always returning false.
what I've understood was, when I'm creating a new account, the validateJwt
function return as invalid so, my req.user._id
is undefined
when isAutheticated()
function try to attach user to req
throwing the 401 error. is it how it works and I really need to create a new account and after login using facebook button or can I create a new account and be redirected with all user information right after that (what I'm not getting)
I hope that's clear now...thanks again. and sorry for my english.
I have same issue. No user login after all social auth providers signups. For example, you need to click "facebook", then you accept, then being redirected to site. We want user to be signed in for that moment, but now user need to click "facebook" again(on login page).
@TimPchelintsev I think that's an issue with how the generator isn't able to persist the user token across browser sessions
@Awk34 I managed to solve this by replacing current "..Async" code with old versions in passport.js files. Also had problem with Facebook not returning email, fixed that with adding "profileFields: ['id', 'emails', 'name']" to "new FacebookStrategy.." part in facebook passport.js.
@TimPchelintsev could you show the code?
@elmeerr I replaced this code from server/auth/facebook/passport.js(similarly for other providers):
import passport from 'passport';
import {Strategy as FacebookStrategy} from 'passport-facebook';
export function setup(User, config) {
passport.use(new FacebookStrategy({
clientID: config.facebook.clientID,
clientSecret: config.facebook.clientSecret,
callbackURL: config.facebook.callbackURL,
profileFields: [
'displayName',
'emails'
]
},
function(accessToken, refreshToken, profile, done) {
User.findOneAsync({
'facebook.id': profile.id
})
.then(user => {
if (user) {
return done(null, user);
}
user = new User({
name: profile.displayName,
email: profile.emails[0].value,
role: 'user',
provider: 'facebook',
facebook: profile._json
});
user.saveAsync()
.then(user => done(null, user))
.catch(err => done(err));
})
.catch(err => done(err));
}));
}
with old variant of generator(save instead of saveAsync). Also I added profileFields: ['id', 'emails', 'name']
to solve problem with Facebook not returning profile.emails.
var passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;
exports.setup = function (User, config) {
passport.use(new FacebookStrategy({
clientID: config.facebook.clientID,
clientSecret: config.facebook.clientSecret,
callbackURL: config.facebook.callbackURL,
profileFields: ['id', 'emails', 'name'] // <-- find this on stackoverflow
},
function(accessToken, refreshToken, profile, done) {
User.findOne({
'facebook.id': profile.id
},
function(err, user) {
if (err) {
return done(err);
}
if (!user) {
console.log(profile);
user = new User({
name: profile.displayName,
email: profile.emails[0].value,
role: 'user',
username: profile.username,
provider: 'facebook',
facebook: profile._json
});
user.save(function(err) {
if (err) done(err);
return done(err, user);
});
} else {
return done(err, user);
}
})
}
));
};
No investigation on this. It was quick intuitive solution, it will be interesting to understand what is going on there..
@TimPchelintsev have you solved the signup problem with this code?
Just spent the last couple of hours nutting out this problem, before finding this....
The issue as I experienced it can be recreated in the stock generated app:
The problem lies in the server/auth/facebook/passport.js file as @TimPchelintsev mentioned and is caused by Mongoose/Bluebird interactions.
Mongoose's save()
function callback signature is function (err, product, numberAffected)
, but Bluebird expects only 2 parameters, so it wraps the multiple values in an array.
The save succeeds, but what should be a single User object passed to the done(...)
passport callback, is in fact an array consisting of the actual User object and the number 1 (the number of documents affected by the create).
The passport code checks for the existence of an object and then happily passes it around as a User object, however none of the property access' work because we are not dereferencing the array.
On subsequent authentications, the User record already exists in the database and a single User object is correctly returned by the findOneAsync call at the top of the function.
I fixed this by replacing the saveAsync call with
user = new User({
name: profile.displayName,
email: profile.emails[0].value,
role: 'user',
provider: 'facebook',
facebook: profile._json
});
user.saveAsync()
.then(saveResult => {
// mongoose save returns (err, obj, numaffected)
// bluebird only expects 2 arguments so it wraps the extras in an array
var user = saveResult[0];
done(null, user);
})
.catch(err => done(err));
That's worked @taotau. Thanks!!! I hope the guys update the function to work like this.
using the default sintax used by generator, would be:
user.saveAsync()
.then(function(user) {
return done(null, user[0]);
})
sorry to take so long to respond, I was working in another project.
Thank you guys...
Hi, I'm facing a problem with social signup because its not logging after its created as in local signup. When redirects, api/users/me is not accessible..is unauthorized (401), different from what i get in local signup, that redirects with user information.
in facebook/index I have default gets
and in auth.service I have the default functions
Could anyone help me with this...Am I missing something?
Thanks in advance.