I wrote my custom method to login, but I'm blocked at the very last step: the effective login of the client.
I believe I'm correctly logged in server-side but no client side:
LoginTokens
(when
&
hashedToken
) in DB.this.userId
).Accounts.validateLoginAttempt(function (attempt)
is allowed, contains the right user and returns no error.Meteor.loggingIn()
is false
and Meteor.user()
is null
Accounts.onLogin(function(user)
returns fine the user._id
So I assume it's an issue about the return to the client (like a user._id) - but I'm lost and think I need an experienced critic eye.
p.s.: I have accounts-base@1.4.0 & accounts-password@1.5.0
Login method (called normally from client)
Meteor.methods({
logTwo (userfinal, passfinal) {
// Consistency var check
check(userfinal, String);
const passwordValidator = {digest: String, algorithm: String};
check(passfinal, passwordValidator);
// check user
const getUser = Accounts.findUserByEmail(userfinal);
if (!getUser) {throw invalidLogin();}
// check password
const checkPassword = Accounts._checkPassword(getUser, passfinal);
if (checkPassword.error) {throw invalidLogin();}
// get user's id
var userID = getUser._id
// logic here
console.log('code verified'); // rightly printed
// below, I tried with or without methodArguments (this, 'login', {user: userfinal,password: passfinal},
// and (this, 'login', '',
Accounts._attemptLogin(this, 'login', {user: userfinal,password: passfinal}, {
type: '2FALogin',
userId: userID,
});
},
});
Accounts.validateLoginAttempt(function (attempt) {
console.log(attempt); // rightly printed
if (attempt.type === '2FALogin' && attempt.methodName === 'login') {
console.log('allowed'); // rightly printed
return true;
}
if (attempt.error) {
console.log('login error: ' + attempt.error);
}
});
return of Accounts.validateLoginAttempt(function (attempt) (console.log(attempt))
{ type: '2FALogin',
allowed: true,
methodName: 'login',
methodArguments:
[ 'bob@bob.com',
{ digest: '70bd58ff28477...', // digest here ok
algorithm: 'sha-256' } ],
user:
{ _id: '6i6vLjc8Ssg6SGJNf',
createdAt: 2017-11-01T15:08:52.332Z,
services: { password: [Object], resume: [Object] },
emails: [ [Object], [Object] ],
_loggedIn: true,
},
connection:
{ id: 'xFLv3XZWztxsdxckM',
close: [Function: close],
onClose: [Function: onClose],
clientAddress: '127.0.0.1',
httpHeaders:
{ 'x-forwarded-for': '127.0.0.1',
'x-forwarded-proto': 'ws',
host: 'localhost:3000',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36',
'accept-language': 'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7,la;q=0.6' } } }
I figure how to manage it.
Meteor.loginWithPassword
was not an option, as it's not working inside a Meteor.call
sourceMeteor.connection.setUserId(response)
on call's return, but nothing was stored in localStorage
: so at every refresh, I was logged out.I needed Accounts.callLoginMethod
, from accounts-base:
login method which on success calls
this.setUserId(id)
andAccounts._setLoginToken
on the server and returns an object with fieldsid
(containing the user id),token
(containing a resume token), and optionallytokenExpires
.
Also, in the method, I needed to return the function Accounts._attemptLogin
(or nothing could be handled by the client).
So, to resume:
On client
Accounts.callLoginMethod({
methodName: 'logTwo',
methodArguments: [
{
user: userfinal,
password: passfinal
},
],
userCallback: function(error) {
if (!error) {
// handle return here
}
}
});
On server
Meteor.methods({
logTwo (options) {
// Consistency var check
const passwordValidator = {digest: String, algorithm: String};
check(options, {
user: String,
password: passwordValidator
});
// check user
const getUser = Accounts.findUserByEmail(options.user);
if (!getUser) {throw invalidLogin();}
// check password
const checkPassword = Accounts._checkPassword(getUser, options.password);
if (checkPassword.error) {throw invalidLogin();}
// get user's id
var userID = getUser._id
// logic here
return Accounts._attemptLogin(this, 'login', '', {
type: '2FALogin',
userId: userID,
});
},
});
Accounts.validateLoginAttempt(function (options) {
if (options.type === '2FALogin' && options.methodName === 'login') {
return true;
}
if (options.error) {
console.log('login error: ' + options.error);
}
});