如何在涉及两个模型时创建身份验证(email-token/digest)link?

How to create authentication (email-token/digest) link when two models are involved?

我一直在关注 railstutorial.org。在本教程中,我们 a.o。学习如何创建一个 token/digest 和一个邮件程序来激活帐户。它将摘要保存到数据库中,并发送一封带有 link 的电子邮件,其中包含令牌 + 电子邮件地址。然后,身份验证控制器方法根据数据库中的摘要检查电子邮件令牌组合。

现在我遇到了类似的情况,但有一个复杂的因素:有usersorganizations。我的用例是组织可以邀请用户成为该组织的成员。在用户真正成为该组织的成员之前,用户需要使用身份验证 link 来确认这一点。

下面是我当前的设置,其中包括保存到 User table 的摘要和带有用户电子邮件地址和令牌的 link。问题是,如果用户点击认证link,认证方法仍然不知道应该将用户添加到哪个组织。它只有一个电子邮件地址和令牌。

如何才能知道是哪个组织发出了邀请?此外,我们当然不希望用户能够以这样一种方式操纵 link,即用户可以将自己添加到与邀请用户加入的组织不同的组织中。


控制器方法:

def request
  @organization = current_organization
  @user = User.find(email: params[:user][:email])
  @user.send_invitation(@organization)
end

模型方法:

def send_invitation(organization)
  create_invite_digest  # Uses other model method to create digest and token.
  update_columns(invite_digest: self.invite_digest)
  UserMailer.add_user(self, organization).deliver_now
end

邮件方法:

def add_user(user, organization)
  @user = user
  @organization = organization
  mail to: user.email, subject: "Please confirm"
end

邮件查看:

<%= adduser_url(@user.invite_token, email: @user.email) %>

用于验证的控制器方法:

def adduser
  user = User.find_by(email: params[:email])
  if user && user.authenticated?(:invite, params[:id])
    user.add_role(organization)  # Should add user to organization, but then it needs to know which organization
    flash[:success] = "User added"
    redirect_to root_path
  end
end

添加用户的模型方法:需要有关要将用户添加到的组织的信息。

def add_role(organization)
end

可能最简单的事情是创建某种包含令牌 user_id 和 organization_id 的邀请模型。这将帮助您跟踪参考文献,并为将来提供灵活性。

您也可以通过这种方式添加额外的元数据(例如 accepted_at),并可能添加邀请仅在一定时间内有效的能力(通过使用邀请 created_at,例如)。

我有一个类似的项目,我有一个邀请模型和参与者模型(会员资格也是一个好名字)。

邀请有 user_email、organization_id 和令牌。它有一个在创建邀请时创建的相关邮件程序。

然后用户将通过电子邮件收到邀请并点击以在网站上查看它,使用邀请的令牌作为查找参数。邀请有机会"accept",这真是创造参与者记录的能力(user_id,organization_id)。用户必须为此登录,这可能是新注册或登录。仅当邀请令牌有效(存在且尚未使用)时才会创建参与者。我在邀请 "accepted_at" 上有一个日期,用于了解其状​​态以及是否可用于创建参与者。用户无需使用特定的电子邮件地址进行注册,他们只需访问邀请即可接受邀请。用户只能成为组织中的参与者一次。参与者的角色由控制器决定。

这对我来说真的很管用。我还计划添加一个 participant_request 模型,允许登录用户请求成为组织的参与者。然后,该组织可以选择查看请求和 "accept" 或 "deny" 他们 - 创建参与者或拒绝请求。日期时间将根据请求了解其状态。

如果您想要更多模型细节,我可以提供。这可能就足够了。