设计可确认:令牌无效错误 [英] Devise confirmable: Token is invalid error

查看:135
本文介绍了设计可确认:令牌无效错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去3个小时之久...设置了可确认的电子邮件,事实证明这很容易,但是从那开始是很虚假的.无论如何,我努力克服了许多错误,未定义的方法和变量,并竭尽全力向我发送了一些东西……但是我无法确认.我已经在确认控制器的内幕下无济于事...它只是没有确认正确.我不知道我在做什么错,但始终将我重定向到重新发送确认说明"页面...

更新:掌握了因其臭名昭著的无效令牌错误而生成的错误.再过一个小时的研究并没有解决任何问题,我一直听到您需要像在我看来的那样使用@token……这应该可以使它起作用,但不能起作用.

控制器:默认Devise确认控制器:

    class  ConfirmationsController < Devise::ConfirmationsController
  # GET /resource/confirmation/new
  def new
    self.resource = resource_class.new
  end

  # POST /resource/confirmation
  def create
    self.resource = resource_class.send_confirmation_instructions(resource_params)
    yield resource if block_given?

    if successfully_sent?(resource)
      respond_with({}, location: after_resending_confirmation_instructions_path_for(resource_name))
    else
      respond_with(resource)
    end
  end

  # GET /resource/confirmation?confirmation_token=abcdef
  def show
    self.resource = resource_class.confirm_by_token(params[:confirmation_token])
    yield resource if block_given?

    if resource.errors.empty?
      set_flash_message(:notice, :confirmed) if is_flashing_format?
      respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
    else
      respond_with_navigational(resource.errors, status: :unprocessable_entity){ render :new }
    end
  end

  protected

    # The path used after resending confirmation instructions.
    def after_resending_confirmation_instructions_path_for(resource_name)
      new_session_path(resource_name) if is_navigational_format?
    end

    # The path used after confirmation.
    def after_confirmation_path_for(resource_name, resource)
      if signed_in?(resource_name)
        authenticated_root_path(resource)
      else
        unauthenticated_root_path
      end
    end

end

邮件视图:

 <p>Welcome <%= @email %>!</p>

<p>You can confirm your account email through the link below:</p>

<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>

路线片:

devise_for :users, controllers: { registrations: 'registrations', sessions: 'sessions', confirmations: 'confirmations'}

devise_scope :user do
  authenticated :user do

    root :to => 'homepage#index', as: :authenticated_root
    end

  unauthenticated :user do
    root :to => 'devise/sessions#new', as: :unauthenticated_root
  end
end

新的确认誓言

<h2>Resend confirmation instructions</h2>

<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>

  <div><%= f.label :email %><br />
  <%= f.email_field :email, autofocus: true %></div>

  <div><%= f.submit "Resend confirmation instructions" %></div>
<% end %>
<%= devise_error_messages!(:email) %>
<%= render "devise/shared/links" %>

此外,我还重新设计了错误帮助器以使其显示自定义错误(不知道那是什么使它弄乱了,但是这里是:

module DeviseHelper
  def devise_error_messages!(field)
    return nil if resource.errors.empty?
    messages = resource.errors.full_messages_for(field).map { |msg| content_tag(:li, msg) }.join
    if resource.errors.full_messages_for(field) != []
      html = <<-HTML
    <div class="alert alert-error alert-block"> <button type="button"
    class="close" data-dismiss="alert">x</button>
      #{messages}
    </div>
    HTML

    html.html_safe
    else
      return nil
    end
  end

end

解决方案

好吧,经过10个小时的搏斗,我决定从零开始重新调整,并使其在本地以及heroku上都可以使用.在Rails 4和Devise 3.2.4中遵循此教程: https://github.com/plataformatec/devise/wiki/How-To:-Add-:confirmable-to-Users .然后我很长一段时间都出现了Undefined router错误,所以我看了一下注册控制器,并替换了它的默认版本中的6或7行,这里是指向另一个更好地解释它的tut的链接

UPDATE: Got hold of the error that is being generated at its the infamous Invalid token error. Again hour of research solved nothing I keep hearing that you need to use @token just like I do in my view... and it supposed to make it work but it does not.

Controller: Default Devise confirmations controller:

    class  ConfirmationsController < Devise::ConfirmationsController
  # GET /resource/confirmation/new
  def new
    self.resource = resource_class.new
  end

  # POST /resource/confirmation
  def create
    self.resource = resource_class.send_confirmation_instructions(resource_params)
    yield resource if block_given?

    if successfully_sent?(resource)
      respond_with({}, location: after_resending_confirmation_instructions_path_for(resource_name))
    else
      respond_with(resource)
    end
  end

  # GET /resource/confirmation?confirmation_token=abcdef
  def show
    self.resource = resource_class.confirm_by_token(params[:confirmation_token])
    yield resource if block_given?

    if resource.errors.empty?
      set_flash_message(:notice, :confirmed) if is_flashing_format?
      respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
    else
      respond_with_navigational(resource.errors, status: :unprocessable_entity){ render :new }
    end
  end

  protected

    # The path used after resending confirmation instructions.
    def after_resending_confirmation_instructions_path_for(resource_name)
      new_session_path(resource_name) if is_navigational_format?
    end

    # The path used after confirmation.
    def after_confirmation_path_for(resource_name, resource)
      if signed_in?(resource_name)
        authenticated_root_path(resource)
      else
        unauthenticated_root_path
      end
    end

end

Mailer view:

 <p>Welcome <%= @email %>!</p>

<p>You can confirm your account email through the link below:</p>

<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>

Routes piece:

devise_for :users, controllers: { registrations: 'registrations', sessions: 'sessions', confirmations: 'confirmations'}

devise_scope :user do
  authenticated :user do

    root :to => 'homepage#index', as: :authenticated_root
    end

  unauthenticated :user do
    root :to => 'devise/sessions#new', as: :unauthenticated_root
  end
end

New Confirmations vew

<h2>Resend confirmation instructions</h2>

<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>

  <div><%= f.label :email %><br />
  <%= f.email_field :email, autofocus: true %></div>

  <div><%= f.submit "Resend confirmation instructions" %></div>
<% end %>
<%= devise_error_messages!(:email) %>
<%= render "devise/shared/links" %>

Also, I have reworked devise error helper to have it display custom errors (Dont know may that is what messing it up but here it is:

module DeviseHelper
  def devise_error_messages!(field)
    return nil if resource.errors.empty?
    messages = resource.errors.full_messages_for(field).map { |msg| content_tag(:li, msg) }.join
    if resource.errors.full_messages_for(field) != []
      html = <<-HTML
    <div class="alert alert-error alert-block"> <button type="button"
    class="close" data-dismiss="alert">x</button>
      #{messages}
    </div>
    HTML

    html.html_safe
    else
      return nil
    end
  end

end

解决方案

Ok so after 10 hours of fightting I decided to restrt from scratch and have made it work on local as well as on heroku. Follow this tut for Rails 4 and Devise 3.2.4: https://github.com/plataformatec/devise/wiki/How-To:-Add-:confirmable-to-Users. Then i got Undefined router error for a good while so I look at the registrations controller and replaced the 6 or 7 lines found in the default version of it heres the link to another tut that explains it better https://github.com/plataformatec/devise/wiki/How-To%3a-Redirect-to-a-specific-page-on-successful-sign-up-%28registration%29:

Registrations controller action (Working)

# The path used after sign up for inactive accounts. You need to overwrite
# this method in your own RegistrationsController.
 def after_inactive_sign_up_path_for(resource)
   after_sign_in_path_for(resource) 
 end

Viola! It went through without any hassle. So something that should only take 5 min only taken me 10 hours. That's efficiency right there!

Also I got it to work with mobile format just in case some of you have problems with it:

confirmations controller:

# GET /resource/confirmation?confirmation_token=abcdef
  def show
    self.resource = resource_class.confirm_by_token(params[:confirmation_token])
    yield resource if block_given?

    if resource.errors.empty?
      set_flash_message(:notice, :confirmed) if is_flashing_format?
      respond_to do |format|
        format.html{redirect_to unauthenticated_root_path}
        format.mobile {redirect_to unauthenticated_root_path, notice: 'Confirmation success!'}
      end   
    else
      respond_to do |format|
        format.html{render :new}
        format.mobile {redirect_to unauthenticated_root_path, alert: 'Failure, already confirmed'}
      end
    end
  end

If you have more technically correct answer post it and I will accept it if its better than mine!

这篇关于设计可确认:令牌无效错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆