【问题标题】:Email verification with Strongloop loopback - verification token returned使用 Strongloop 环回的电子邮件验证 - 返回验证令牌
【发布时间】:2014-12-04 07:13:07
【问题描述】:

我目前正在开发 API。我正在使用 Strongloop(环回)。

我正在尝试在用户注册时实施电子邮件验证。我有一个“用户”模型,它扩展了内置的“用户”模型。

现在,当用户注册 (POST /users) 时,会发送一封电子邮件,其中包含指向 /users/confirm 的链接,其中包含三个适当的参数,即 uid、redirect 和一个令牌。当用户点击链接时,后者的电子邮件地址被正确验证(emailVerification 字段变为真)。

但是,我注意到在 /users 上发出 POST 请求时,响应包含验证令牌。这是正常的吗?验证令牌不是只能通过发送的电子邮件访问吗?

因为事实上,通过在 /users 上发出 POST 请求并在响应中获取验证令牌,可以轻松地使用适当的参数(包括验证令牌)向用户/确认发送另一个请求并验证电子邮件地址,即使地址不存在。

我是 Strongloop 的新手,也许我遗漏了一些东西。你们能帮忙吗?

【问题讨论】:

  • 我正在为这些类型的问题构建一个示例存储库,因为它经常出现。你可以在github.com/strongloop/loopback-faq-user-management 看到我现在拥有的东西。还没有完成,因为我目前正在处理它,但我希望在星期五之前完成。
  • 听起来不错。敬请期待。
  • 示例已完成,请为答案投票。

标签: loopbackjs strongloop


【解决方案1】:

【讨论】:

  • 您是否建议我们必须在应用程序中创建一个新的用户模型?为什么不能使用 User 模型而不是 user 模型?
  • 是的,我们建议您扩展内置用户模型以方便配置。注意你在common/models 中没有User.json 或User.js,所以用user 扩展内置会更容易,然后你可以修改common/models/user.js 和common/models/user.json任何其他脚手架模型。
【解决方案2】:

如果您想创建用户注册验证链接但不使用内置用户模式,那么您需要创建验证令牌然后发送链接。我已经添加了这两种方法。您还需要使用带有一个参数的远程方法谁是对象类型:你需要通过注册电子邮件发送参数。方法是这样的....这里我们使用user=any variable name,modelN=model name

modelN.sendVerificationEmail = function (data, callback) {
  var user = loopback.models.modelN;

  if (!data.email) {
    return callback(commonUtils.buildError(
      'Recipient email is required.', 400, 'EMAIL_REQUIRED'
    ));
  }

  if (!emailValidator.validate(data.email)) {
    return callback(commonUtils.buildError(
      'Must provide a valid email.', 400, 'INVALID_EMAIL'
    ));
  }

  var findOneuserPromise
    = modelN.findOne({ 'where': { 'email': data.email }});

  findOneBusinessEmployeePromise.then(function (user) {
    if (!user) {
      return callback();
    }

    var sendVerificationEmailPromise
      = anothermodelname.sendVerificationEmail(user.id);

    sendVerificationEmailPromise.then(function () {
      callback();
    });

    sendVerificationEmailPromise.then(null, function (error) {
      callback(error);
    });
  });

  findOneuserPromise.then(null, function (error) {
    callback(error);
  });
};

我已经添加了另一个模型模型方法,然后添加了这个,....

anothermodelname.sendVerificationEmail = function (userid) {
  var modelN = loopback.models.modelN;
  var Email = loopback.models.Email;
  var deferred = Q.defer();
  var findByIduserPromise = modelN.findById(userId);

  findByIduserPromise.then(function (user) {
    if (!user) {
      return deferred.reject(commonUtils.buildError(
        'Unknown "modelN" id "' + userId + '".',
        404, 'MODEL_NOT_FOUND'
      ));
    }
    if (!user.verificationToken) {
      return deferred.resolve(true);
    }


    modelN.generateVerificationToken(user,
      function (verificationTokenError, verificationToken) {
        if (verificationTokenError) {
          return deferred.reject(verificationTokenError);
        }

        user.verificationToken = verificationToken;

        var saveuserPromise = user.save();

        saveuserPromise.then(function (updateduser) {
          var link = emailConf.clientBaseUrl +
            emailConf.verifyEmailRedirect + '?uid=' +
            updateduser.id + '&token=' +
            updateduser.verificationToken;
               console.log("check+link:",link);
          /*eslint camelcase: [0, {properties: "never"}]*/
          emailOptions.to = updateduser.email;
          emailOptions.template = { 'name': 'verify' };
          emailOptions.global_merge_vars = [];

          emailOptions.global_merge_vars.push({
            'name': 'USER_NAME',
            'content': updateduser.name
            || updateduser.username || updateduser.email
          });

          emailOptions.global_merge_vars.push({
            'name': 'LINK',
            'content': link
          });
          Email.send(emailOptions, function () {});

          deferred.resolve(true);
        });

        saveuserPromise.then(null, function (error) {
          deferred.reject(error);
        });
      });
  });

  findByIduserPromise.then(null, function (error) {
    deferred.reject(error);
  });

  return deferred.promise;
};

【讨论】:

  • 如果任何人有任何问题然后问我
【解决方案3】:

@user2483431,验证电子邮件会在响应中公开电子邮件验证令牌以及用户 ID。正如您正确指出的那样,它有欺骗系统的风险。一种解决方案是从响应中去除令牌值。

在afterRemote里面供用户创建,你可以使用,

user.verify(options, function(err, response, next2) {
  if (err) {
    // error handling code
  }
  // stripping off verificationToken from response for security
  var replacementText = "check email"
  context.result.verificationToken = replacementText;
  next();
});

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2014-10-07
    • 2022-01-09
    • 2018-05-14
    • 2020-12-23
    • 2014-09-26
    • 2019-04-04
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    相关资源
    最近更新 更多