Meteor - 密码恢复/电子邮件确认动态网址

时间:2018-03-09 03:41:50

标签: email url meteor client-side meteor-accounts

基本上,我在meteor和 meteor startup 上使用帐户基础包,我设置了服务器应该用于密码恢复的模板邮件,电子邮件确认邮件等

例如,在流星启动时的我的server / startup.js中,我做了很多事情:

  Accounts.urls.verifyEmail = function (token) {
        return Meteor.absoluteUrl(`verify-email/${token}`);
      };

  Accounts.emailTemplates.verifyEmail.html = function (user, url) {
        return EmailService.render.email_verification(user, url);
      };

问题是我的应用程序托管在多个主机名,例如 company1.domain.com company2.domain.com ,< strong> company3.domain.com 如果客户想要从company1.domain.com重置密码,则提供的恢复网址应为company1.domain.com/recovery。

如果其他客户尝试连接 company2.domain.com,则恢复网址应为company2.domain.com

根据我的理解,这实际上是不可行的,因为Accounts Package使用的方法是&#34; Meteor.absoluteUrl()&#34;,它返回服务器ROOT_URL变量(a单个服务器)。

在客户端,我根据window.location.href执行了很多操作,但在尝试重置密码或尝试确认电子邮件地址时,我似乎无法将此网址发送到服务器。< / p>

我试图找到一种方法来动态生成网址,具体取决于客户端发出请求的主机,但由于网址是在服务器端生成的,我不能找到一种优雅的方式。我想我可能在尝试重置密码或创建帐户并在那里动态设置ROOT_URL变量之前调用流星服务器方法,但这似乎不安全且有风险,因为两个人可能很容易尝试重置时间框架可能搞砸了,或者人们可能会滥用它。

有没有办法告诉服务器,从客户端,我想为当前电子邮件生成的URL必须是客户端当前的位置? 我希望能够覆盖基于帐户的meteor包中的某些功能,并实现以下目标:

 Accounts.urls.verifyEmail = function (token, clientHost) {
        return `${clientHost}/verify-email/${token}`;
      };

  Accounts.emailTemplates.verifyEmail.html = function (user, url) {
        return EmailService.render.email_verification(user, url);
      };

但是我不确定这是否可能,在幕后的情况下,我不会有任何真实的经验。&#34;基础软件包的功能,我喜欢发生的事情,除了生成的url总是一样的。

1 个答案:

答案 0 :(得分:0)

好的,所以我设法找到了一种方法来实现我想要的东西,它有点黑客,但是嘿..

基本上,useraccounts具有以下功能:寄存器at-form中的任何隐藏输入都将添加到用户配置文件中。所以我添加了一个隐藏字段来存储用户当前位置。

AccountsTemplates.addField({
  _id: 'signup_location',
  type: 'hidden',
});

渲染模板时,我用jQuery填充这个隐藏的输入。

Template.Register.onRendered(() => {
  this.$('#at-field-signup_location').val(window.location.href);
});

然后,当我实际发送emailVerification电子邮件时,如果可用,我可以查找此值。

  Accounts.urls.verifyEmail = function (token) {
    return Meteor.absoluteUrl(`verify-email/${token}`);
  };

  Accounts.emailTemplates.verifyEmail.html = function (user, url) {
    const signupLocation = user.profile.signup_location;
    if (signupLocation) {
      let newUrl = url.substring(url.indexOf('verify-email'));
      newUrl = `${signupLocation}/${newUrl}`;
      return EmailService.render.email_verification(user, newUrl);
    }

    return EmailService.render.email_verification(user, url);
  };

所以这对signUp流程进行了修复,我可能会对resetPassword和resendVerificationUrl使用类似的概念,因为signupLocation现在位于用户配置文件中。

您应该在设置中保留每个子域的数组,并在用户配置文件中保留相应的ID的ID,因此如果您的域将来发生更改,则该引用仍然有效且一致。