2013-09-06 12 views
40

RozwiązanieAktualizacja do opracowania 3,1 => Pierwsze zresetować hasło tokenu jest nieprawidłowy

Dzięki tej gist postać Stevena Harman, mam to działa. devise_mail_helpers.rb

module Features 
    module MailHelpers 

    def last_email 
     ActionMailer::Base.deliveries[0] 
    end 

    # Can be used like: 
    # extract_token_from_email(:reset_password) 
    def extract_token_from_email(token_name) 
     mail_body = last_email.body.to_s 
     mail_body[/#{token_name.to_s}_token=([^"]+)/, 1] 
    end 

    end 
end 

Dodałem plik devise_mail_helpers.rb w tym samym folderze co cechy specyfikacji i napisał ten spec.

require 'devise_mail_helpers.rb' 
include Features 
include MailHelpers 
describe "PasswordResets" do 
    it "emails user when requesting password reset" do 
    user = FactoryGirl.create(:user) 
    visit root_url 
    find("#login_link").click 
    click_link "Forgot your password?" 
    fill_in "Email", :with => user.email 
    click_button "Send instructions" 
    current_path.should eq('/users/sign_in') 
    page.should have_content("You will receive an email with instructions about how to reset your password in a few minutes.") 
    last_email.to.should include(user.email) 
    token = extract_token_from_email(:reset_password) # Here I call the MailHelper form above 
    visit edit_password_url(reset_password_token: token) 
    fill_in "user_password", :with => "foobar" 
    fill_in "user_password_confirmation", :with => "foobar1" 
    find('.signup_firm').find(".submit").click 
    page.should have_content("Password confirmation doesn't match Password") 
    end 
end 

Zajmuje się specyfikacją, aby działało w przeglądarce spójrz na odpowiedź Dave'a poniżej.

oryginalne pytanie

W moich szynach 4 app, mam zmodernizowane devise do 3,1 i pobiegł rails s, to mam to:

`raise_no_secret_key': Devise.secret_key was not set. 
Please add the following to your Devise initializer: (RuntimeError) 
config.secret_key = '--secret--' 

dodałem tajny klucz do inicjatora opracować .

Po tym pojawia się następujący błąd podczas próby zresetowania hasła

Reset password token is invalid 

Wygląda tokena, który jest wysyłany na adres e-mail nie jest poprawny. Wszystko inne działa. Loguję się i wychodzę jak ciepły nóż przez masło.

Aktualizacja

Teraz myślę, że to musi być coś z szyfrowaniem z reset_password_token tu ze spec cecha:

user = FactoryGirl.create(:user, 
:reset_password_token => "something", 
:reset_password_sent_at => 1.hour.ago) 
visit edit_password_url(user, :reset_password_token => 
    user.reset_password_token) 
fill_in "user_password", :with => "foobar" 
click_button "Change my password" 
page.should have_content("Password confirmation doesn't match Password") 

pojawienia się błędu jest:

Failure/Error: page.should have_content 
("Password confirmation doesn't match Password")   
expected to find text "Password confirmation doesn't match Password" in 
"Reset password token is invalid" 

Jakieś pomysły na temat tego, czego mi brakuje?

Odpowiedz

91

Jeszcze raz skomentowałeś na my similar question i znalazłem odpowiedź, która również może ci pomóc.

Aktualizacja do programu Devise 3.1.0 pozostawiła po sobie "widok", którego nie dotykałem od pewnego czasu. Zgodnie z this blog post, musisz zmienić swój program pocztowy Devise, aby używał @token zamiast starego @resource.confirmation_token.

Znajdź w app/views/<user>/mailer/reset_password_instructions.html.erb i zmienić go na coś takiego:

<p>Hello <%= @resource.email %>!</p> 
<p>Someone has requested a link to change your password, and you can do this through the link below.</p> 
<p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @token) %></p> 
<p>If you didn't request this, please ignore this email.</p> 
<p>Your password won't change until you access the link above and create a new one.</p> 

To powinno rozwiązać wszelkie problemy tokenów potwierdzeń masz. Prawdopodobnie rozwiąże to również wszelkie problemy z kodem odblokowania lub potwierdzenia.

+0

To jest poprawne rozwiązanie, aby działało w przeglądarce, ale jak to przetestować? –

+0

W skrócie, Twój test Rspec powyżej wygląda na to, że powinien wystarczyć. Zakładając, że problem "nieważnego tokena" zniknął, a jeśli nie działa w określonym miejscu, powinieneś udostępnić błąd. Strategicznie rzecz biorąc, połączenie Rspec lub Cucumber z email_spec powinno umożliwić automatyczne przetestowanie tego. Moje połączone pytanie i [to wiki] (https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Cucumber) zawierają więcej informacji o tym, jak przetestować Devise z ogórkiem. –

+0

test przechodzi. Zanim rozwiązałem problem, nie udało mu się "nieprawidłowy token". –

7

Chyba już zmodernizowane opracować nie v3.1 v3.01, ponieważ config.secret_key. Myślę więc, że jest to w jakiś sposób związane z nową funkcją programistyczną - tajnym kluczem.
znalazłem dwie rewizje dla tajnego klucza funkcji, które mogą być pomocne dla lepszego zrozumienia: https://github.com/plataformatec/devise/commit/32648027e282eb4c0f4f42e9c9cc0c961765faa8 https://github.com/plataformatec/devise/commit/d56641f514f54da04f778b2a9b816561df7910c2

Prawdopodobnie znajdziesz coś przydatnego dla Ciebie na http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/ również.
Ponadto można grep reset_password_token na https://github.com/plataformatec/devise/compare/v3.0...v3.1.0.

EDIT
Czytaj dalej http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/:

  • Devise Mailer teraz otrzymuje jeden dodatkowy symboliczny argument w każdej metodzie . Jeśli dostosowałeś program pocztowy Devise, musisz go zaktualizować.Wszystkie widoki mailers również muszą być aktualizowane, aby użyć @token, jak pokazano here, zamiast pobierania tokenu bezpośrednio z zasobu;
+0

Dzięki! Zbadałem trochę więcej. Wiem o zmianach w obsłudze tokenów w Devise. Tak więc musiałem pracować w przeglądarce. Ale jak to przetestować ?. W komentarzu do [bloga] są pewne wskazówki (http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/) .Do drogi Poprawiłem literówkę 3.01 na 3.1. –

7

Miałem ten błąd na specyfikacji. Próbowałem ręcznie ustawić reset_password_token na User, więc mogłem po prostu przekazać token do edit_user_password_path. Jednak tokeny resetowania są mieszane, więc ustawienie ich ręcznie nie będzie działać. Ups! Aby uniknąć tego błędu, ustawiłem reset_token na równi z faktycznym generowanym tokenem, który jest zwracany przez user.send_reset_password_instructions.

Spec robocza:

require 'spec_helper' 

feature 'User resets password' do 
    scenario 'fills out reset form' do 
    user = create(:user) 
    reset_token = user.send_reset_password_instructions 
    new_password = 'newpassword!' 
    visit edit_user_password_path(user, reset_password_token: reset_token) 

    fill_in :user_password, with: new_password 
    fill_in :user_password_confirmation, with: new_password 
    click_button 'Change my password' 

    expect(page).to have_content(
     'Your password was changed successfully. You are now signed in.' 
    ) 
    end 
end 
+0

To powinno mieć więcej głosów w górę: D – trueinViso

8

FYI, jeśli próbujesz wysłać tokena resetowania hasła za pośrednictwem innego środka (tj inny program pocztowy), można użyć kodu podobnego (wykopane źródła opracować) w swojej klasie użytkownika:

def send_invitation 
    raw, enc = Devise.token_generator.generate(self.class, :reset_password_token) 

    self.reset_password_token = enc 
    self.reset_password_sent_at = Time.now.utc 
    self.save(:validate => false) 

    Notifier.signup_notification(contactable: self, token: raw).deliver 
end 
+0

Klucz to 'self.reset_password_token = enc', i ustawienie' @token = raw'. Dziękuję bardzo! – Mirror318

1

w swojej opracować szablon resetowania hasła upewnij się następującą treść powinna skorygować:

= link_to 'Zmień hasło', edit_password_url (@resource,: reset _password_token => @token)

1

Jak zauważyli inni: powodem jest to, że widok generujący pocztę, który zawiera link resetowania hasła, musi zostać zmieniony.

Widziałem ten błąd, ponieważ wciąż używałem klejnotu devise-i18n-views, który generuje stary link. Usunięcie tego klejnotu i poleganie na widokach, które są teraz częścią klejnotu devise-i18n, rozwiązało problem.