Как вы получаете метод mongoose comparePassword для работы с интерфейсом машинописных файлов [duplicate]

Я искал решение, позволяющее работать $.bind и $.unbind без проблем в динамически добавленных элементах.

Поскольку on () делает трюк для присоединения событий, чтобы создать фальшивую отвязку на тех, к которым я пришел:

const sendAction = function(e){ ... }
// bind the click
$('body').on('click', 'button.send', sendAction );

// unbind the click
$('body').on('click', 'button.send', function(){} );

13
задан Cludch 27 February 2017 в 19:01
поделиться

4 ответа

Я думаю, что у вас такая же проблема, с которой я просто боролся. Эта проблема в вашем звонке. В нескольких учебниках вы вызываете метод .comparePassword() из такой модели.

User.comparePassword(candidate, cb...)

Это не работает, потому что метод находится на schema, а не на model. Единственный способ, которым я смог вызвать метод, - найти этот экземпляр модели, используя стандартные методы запросов mongoose / mongo.

Вот важная часть моего промежуточного программного обеспечения паспорта:

passport.use(
  new LocalStrategy({
    usernameField: 'email'
  },
    function (email: string, password: string, done: any) {
      User.findOne({ email: email }, function (err: Error, user: IUserModel) {
        if (err) throw err;
        if (!user) return done(null, false, { msg: 'unknown User' });
        user.schema.methods.comparePassword(password, user.password, function (error: Error, isMatch: boolean) {
          if (error) throw error;
          if (!isMatch) return done(null, false, { msg: 'Invalid password' });
          else {
            console.log('it was a match'); // lost my $HÏT when I saw it
            return done(null, user);
          }
        })
      })
    })
);

Итак, я использовал findOne({}), чтобы получить экземпляр документа, а затем должен был получить доступ к методам схемы, вставив в свойства схемы документ user.schema.methods.comparePassword

. Несколько различий, которые я заметил:

  1. Mine - это метод instance, а ваш метод static. Я уверен, что существует аналогичная стратегия доступа к методу.
  2. Я обнаружил, что мне пришлось передать хэш функции comparePassword(). возможно, это не обязательно для статики, но мне не удалось получить доступ к this.password
9
ответ дан Nate May 18 August 2018 в 23:41
поделиться
  • 1
    Это действительно работало. Большое спасибо! Один вопрос, почему вы не используете user.comparePassword? Возможно, это устранит вашу проблему this.password ( stackoverflow.com/questions/42415142/… ), поскольку у меня возникла аналогичная проблема. – Cludch 16 March 2017 в 11:58
  • 2
    Если я понимаю, что вы сомневаетесь, причина в том, что Typcript бросает ошибку компиляции. – Nate May 16 March 2017 в 20:14
  • 3
    Я тоже немного борюсь с этой проблемой. Чтобы получить доступ к статическому методу схемы через TypScript, используйте User.schema.statics.hashPassword(). – Jackpile 30 May 2017 в 17:42

У меня была такая же проблема, как и у вас, а затем, наконец, удалось разрешить ее после прочтения документации в типизированных файлах TS mongoose (о которой я раньше не знал, и я не уверен, как долго документы были вокруг), в частности в этом разделе . Я понимаю, что это старый вопрос очень , но я думал, что это может помочь потерянному человеку в будущем. Изменить: я прочитал дату существующего ответа как март 2014 года, а не 14 марта.


Что касается вашего дела, вы захотите следовать аналогичный шаблон, который у вас есть, хотя вам нужно изменить несколько вещей в обоих файлах.

Файл IUser

  1. Переименуйте IUser в IUserDocument.
  2. Импортировать Document из mongoose.
  3. Расширить интерфейс из Document.

Файл модели

  1. Переименуйте все экземпляры IUser на IUserDocument, включая путь к модулю, если вы переименуете файл.
  2. Переименуйте только определение IUserModel к IUser.
  3. Измените то, что IUser простирается от, от IUserDocument, Document до IUserDocument.
  4. Создайте новый интерфейс с именем IUserModel, который простирается от Model<IUser> .
  5. Объявите свои статические методы в IUserModel.
  6. Измените постоянный тип User с Model<IUserModel> на IUserModel, так как IUserModel теперь расширяет Model<IUser>.
  7. Измените аргумент типа на ваш вызов модели с <IUserModel> на <IUser, IUserModel>.

Вот как выглядит ваш файл модели с этими изменениями:

import * as bcrypt from 'bcryptjs';
import { Document, Schema, Model, model } from 'mongoose';

import { IUserDocument } from '../interfaces/IUserDocument';

export interface IUser extends IUserDocument {
    comparePassword(password: string): boolean; 
}

export interface IUserModel extends Model<IUser> {
    hashPassword(password: string): boolean;
}

export const userSchema: Schema = new Schema({
    email: { type: String, index: { unique: true }, required: true },
    name: { type: String, index: { unique: true }, required: true },
    password: { type: String, required: true }
});

userSchema.method('comparePassword', function (password: string): boolean {
    if (bcrypt.compareSync(password, this.password)) return true;
    return false;
});

userSchema.static('hashPassword', (password: string): string => {
    return bcrypt.hashSync(password);
});

export const User: IUserModel = model<IUser, IUserModel>('User', userSchema);

export default User;

И ваш (недавно переименованный) модуль ../interfaces/IUserDocument будет выглядеть так:

import { Document } from 'mongoose';

export interface IUserDocument extends Document {
    email: string;
    name: string;
    password: string;
}
20
ответ дан Harry Shipton 18 August 2018 в 23:41
поделиться
  • 1
    Удивительный ответ, спасибо большое! Вы знаете, как издеваться над IUserModel в TypScript? У меня есть класс Foo, в который введен IUserModel, а некоторые из методов Foo используют статику IUserModel. Я хотел бы придать макету IUserModel фальшивой статикой, как я могу это сделать? – kikar 27 October 2017 в 15:55
  • 2
    Большое спасибо за этот ответ, потребовался день, чтобы найти этот ответ, но он того стоит. БЛАГОДАРЯ – Bence Uszkai 14 May 2018 в 15:45
  • 3
    Это, безусловно, правильное решение исходной проблемы! Принятый ответ - это действительно работа. – leogoesger 26 June 2018 в 18:16
  • 4
    Это должен быть определенно принятый ответ – overcomer 10 July 2018 в 09:40

Я не вижу ваш интерфейс IUser, однако я подозреваю, что вы не включили в него методы. EG

export interface IUser {
    email: string,
    hash: string,
    salt: string,

    setPassword(password: string): void,
    validPassword(password: string): boolean,
    generateJwt(): string
}

машинописный текст затем распознает ваши методы и перестанет жаловаться

0
ответ дан xerotolerant 18 August 2018 в 23:41
поделиться
  • 1
  • 2
    Я не уверен, какая разница будет tbh, хотя способ, которым вы определили методы, также отличается от того, как я это делаю. Я использую формат userSchema.methods.functionName = function(){}. Я не уверен, что это влияет на вас, но может быть. – xerotolerant 27 February 2017 в 19:20
  • 3
    Я изменил способ, как я объявил методы из-за некоторых документов, но это не изменилось. По-прежнему будет проверять ваш ответ, поскольку я получаю время, чтобы сделать – Cludch 28 February 2017 в 19:26
  • 4
    К сожалению, это не работает. – Cludch 2 March 2017 в 18:39
  • 5
    Просто из любопытства вы используете метод hashPassword в классе User или экземпляре? – xerotolerant 3 March 2017 в 03:37
1
ответ дан Max Wilder 30 October 2018 в 11:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: