Ruby on rails 如何创建自动将用户登录到Desive/rails的链接?

Ruby on rails 如何创建自动将用户登录到Desive/rails的链接?,ruby-on-rails,email,ruby-on-rails-4,devise,Ruby On Rails,Email,Ruby On Rails 4,Devise,我试图让注册用户在我的网站上采取一些行动,所以我想通过电子邮件向他们发送一个直接指向该行动的链接 问题是,我希望他们在单击此链接时自动登录 我可以做一些显而易见的事情,比如创建一个独特的令牌,并通过urlmysite.com/my\u funky\u action?login\u bypass\u token=af123fa127ba32传递它,但在我看来这是一个“以前解决过很多次”的问题 因此,有一种简单的方法可以使用rails/Desive来实现这一点?我搜索了Desive文档,但没有成功。

我试图让注册用户在我的网站上采取一些行动,所以我想通过电子邮件向他们发送一个直接指向该行动的链接

问题是,我希望他们在单击此链接时自动登录

我可以做一些显而易见的事情,比如创建一个独特的令牌,并通过url
mysite.com/my\u funky\u action?login\u bypass\u token=af123fa127ba32
传递它,但在我看来这是一个“以前解决过很多次”的问题


因此,有一种简单的方法可以使用rails/Desive来实现这一点?我搜索了Desive文档,但没有成功。

通常不是一件好事

如果您不使用令牌,这意味着您需要构建一个包含电子邮件地址的路径

http://my_app.com/special_action?email=john@sample.com

有鉴于此,任何人只要发送一个如上所述结构的url,替换他们想要的任何电子邮件,就可以作为任何注册用户登录


去买一个代币,确保它在使用时过期,或者在你可以逃脱的最短时间后过期。

使用Desive's recoverable中的代码作为基础,我这样做了

型号:

class User < ActiveRecord::Base
    def set_login_bypass_token
        raw, enc = Devise.token_generator.generate(User, :login_bypass_token)
        self.login_bypass_token = enc
        self.login_bypass_token_set_at = Time.now.utc
        self.save(validate: false)
        raw
     end

     def self.by_bypass_token(token)
         original_token = Devise.token_generator.digest(self, :login_bypass_token, token)
         User.find_by(:login_bypass_token => original_token)
     end
end

“我可以做一些显而易见的事情,比如创建一个独特的令牌并通过url传递它”:为什么要寻找比显而易见的方式更简单的东西呢?因为可能有一些东西已经准备好了,可能隐藏在设计代码中。。。为什么要重新发明轮子?Desive已弃用,后来由于不安全而取消了从确认电子邮件中登录的功能。我不是说我不会使用代币,我只是说我以为有人已经这么做了!
class SomeMailer < ActionMailer::Base
    def send_something
        ...
        @login_bypass_token = @user.set_login_bypass_token
        ...
    end
end
class ApplicationController < ActionController::Base
    layout :application_layout

    protect_from_forgery with: :exception
    before_action :bypass_login
    before_action :authenticate_user!

    private
        def bypass_login
            if params[:login_bypass_token]
                user = User.by_bypass_token(params[:login_bypass_token])
                sign_in(user, :bypass => true) if user
                redirect_to request.path
            end
        end
end
= link_to 'View this awesome page without login!', awesomeness_url(login_bypass_token: @login_bypass_token)