Pas, Bcryptjs, Async/Await: ověření funkce projde každou vstupní heslo jako pravda

0

Otázka

Všechno v mém pasu-místní strategie se zdá být pracovní, s výjimkou verifyCallback, kde truthiness hodnocení validatesPassword vrací true, je-bez ohledu na to. Problém by mohl pramenit z toho, že validatesPassword je asynchronní funkce a Promise {<pending>} výstup, zatímco funkce pracuje mimo pořadí není falešné:

z passwordUtils souboru:

async function validatesPassword(passwordInput, dbHash) {
    let comparedInput = await bcrypt.compare(passwordInput, dbHash)

    //console.log("this is whats returned from compared Input " + comparedInput)
    return comparedInput;
}

Konzoly.protokol volání v validatesPassword normálně tiskne po podmíněné prohlášení, v pase verifyCallback() funkce v můj pas, soubor se nazývá:

 User.findOne(email)
        .then((dbResponse) => {
            //console.log(dbResponse[0][0]);
            let user = dbResponse[0][0];
            if (!user) { return done(null, false); }
            //no error, but also no user 

            const isValid = validatesPassword(password, user.hash);
            //const isValid = false;
            if (isValid) {
                return done(null, user);
            } else {
                return done(null, false);
            }

        })
        .catch((err) => {
            console.log(err);
            done(err);
        });
}


const strategy = new LocalStrategy({ usernameField: 'email', passReqToCallback: true }, verifyCallback);
passport.use(strategy)
...

Jak je vidět výše, jediný způsob, jak lze odvodit z false na výše uvedené podmíněné, je výslovně nastavení isValid k false. Jaký by byl nejlepší způsob, jak se dostat podmíněný čekat na heslo porovnat (validatesPassword) funkce a zhodnotit jeho vrácena logická funkce? Měl jsem promisify validatesPassword a přidat podmíněné uvnitř (já jsem se snažil prováděcí sám marně), že funkce a projít všechny, že verifyCallback funkce v my passport souboru?

2

Nejlepší odpověď

2

validatesPassword() je async funkce. Jako takový, to VŽDY vrátí slib.

Takže, když budeš dělat tohle:

        const isValid = validatesPassword(password, user.hash);
        if (isValid) {
          // ...
        }

To bude vždy být pravdivý, protože isValid je slib, takže if (isValid) bude vždy projít. Místo toho, budete muset získat hodnotu z slíbit, že se buď .then() nebo await například:

        const isValid = await validatesPassword(password, user.hash);
        if (isValid) {
          // ...
        }

Použití await tam, budete muset udělat mateřské funkce async.


Pomocí .then() a kombinovat do kódu můžete ukázat ve své otázce, to může vypadat takto:

User.findOne(email).then((dbResponse) => {
    let user = dbResponse[0][0];
    if (!user) { 
        return done(null, false); 
    }
    return validatesPassword(password, user.hash).then(isValid => {
        done(null, isValid ? user : false);
    });
}).catch((err) => {
    console.log(err);
    done(err);
});

Mějte na paměti několik věcí, o použití async a await:

  1. O async funkce vždy vrací slib.
  2. Vrátí se, že slib, když async funkce narazí na první await a provedení, které async funkce je pozastaven v tomto bodě, ale to se vrací příslib ihned a provedení volání kódu, který obdrží, které slibují pokračuje.
  3. Někdy později, když vnitřní slib, který používáte await s řeší, pak je funkce, která byla dříve pozastaveno na await bude pokračovat v provádění.
  4. Když se nakonec dostal k návratu hodnotu v té funkci, jako je vaše return comparedInput;to , že návratová hodnota pak bude vyřešen hodnota slib, který byl dříve vrátil z async funkce. Takže, když to vypadá jako synchronní návratovou hodnotu, to není. Protože funkce je asyncvrácená hodnota se stává vyřešen hodnota slib, že se vrátí.
  5. Volající pak musí použít buď await nebo .then() získat vyřešen hodnotu z slib.
2021-11-24 06:13:17

Zveřejnil jsem svoje řešení, ocenil bych, kdyby ses podíval a řekl mi, co si myslíš, pokud můžete.
DeltaFlyer

@DeltaFlyer - přidal jsem novou verzi na mou odpověď.
jfriend00
0

jfriend00 odpověď dostal kola se točí v mé hlavě, ale nebyl jsem si jistý, že jsem pochopil na první. Podíval jsem se nahoru pomocí podmiňovací způsob v sliby a podmiňovací, že spoléhat se na sliby a přišel s tímto řešením, kde jsem .pak()'d validatesPassword a pak dodal podmíněné, v rámci které:

...
User.findOne(email)
        .then((dbResponse) => {
            //console.log(dbResponse[0][0]);
            let user = dbResponse[0][0];
            if (!user) { return done(null, false); }
            //no error, but also no user 
            console.log(
                `
                here's the dbResponse Object:
                user: ${user.username},
                password: ${user.hash},   
                `
            );

            validatesPassword(password, user.hash)
                .then((isValid) => {
                    if (isValid) {
                        return done(null, user);
                    } else {
                        return done(null, false);
                    }
                })
                //const isValid = false;


        })
        .catch((err) => {
            console.log(err);
            done(err);
        });
}
...

Nejsem si jistý, jestli je to to, co jfriend00 navrhoval, ale toto řešení zdá se do práce.

2021-11-23 02:03:38

Podívejte se na to, co jsem přidal na mou odpověď. Co máte tady je většinou OK. Jedna věc, kterou chybí, je-li validatesPassword() odmítá, nemusíte zvládnout odmítnutí. Vrátil jsem se, že slib, takže odmítnutí chytí na vyšší úrovni .catch(). Nechat odmítnutí šířit se může zjednodušit chytání chyb.
jfriend00

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................