devise confirmation token is invalid - ruby-on-rails

I added a new migration to a table in my app and I migrate. Since it had errors, I dropped and migrated it. When I signed up for a user and tried to confirm it using email(devise,confirmable) it just won't confirm. It says invalid confirmation token. I have tried restarting the server. Dropping and migrating again, everything possible as far as I know. I am using Rails 3.2.9 and Ruby 1.9.3. Devise version is 3.1.0. Devise is also included in other gems I have added like rails-messaging and active-admin.
Started POST "/users/confirmation" for 127.0.0.1 at 2013-09-16 19:42:47 +0530
Processing by Devise::ConfirmationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"4lMxdlsMqRCJB1doxt/hTCQhUPvAoGPiSbr9wQA/ZAQ=", "user"=>{"email"=>"pro.aravind#gmail.com"}, "commit"=>"Resend confirmation instructions"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."unconfirmed_email" = 'pro.aravind#gmail.com' LIMIT 1
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'pro.aravind#gmail.com' LIMIT 1
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."confirmation_token" = 'cc47150f51ec476aa40ea1d546e27c0dafc37ffc8bb82272a9f2377c863daed1' LIMIT 1
(0.1ms) begin transaction
(0.3ms) UPDATE "users" SET "confirmation_token"='cc47150f51ec476aa40ea1d546e27c0dafc37ffc8bb82272a9f2377c863daed1', "confirmation_sent_at" = '2013-09-16 14:12:47.174313', "updated_at" = '2013-09-16 14:12:47.175384' WHERE "users"."id" = 1
(175.3ms) commit transaction
Rendered devise/mailer/confirmation_instructions.html.erb (0.6ms)
Sent mail to pro.aravind#gmail.com (5099ms)
Date: Mon, 16 Sep 2013 19:42:47 +0530
From: please-change-me-at-config-initializers-devise#example.com
Reply-To: please-change-me-at-config-initializers-devise#example.com
To: pro.aravind#gmail.com
Message-ID: <523711df6bb56_3a029657f88282b#aravind-VPCEB46FGB.mail>
Subject: Confirmation instructions
Mime-Version: 1.0
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: 7bit
<p>Welcome pro.aravind#gmail.com!</p>
<p>You can confirm your account email through the link below:</p>
<p>Confirm my account</p>
Redirected to http://localhost:3000/users/sign_in
Completed 302 Found in 5387ms (ActiveRecord: 0.0ms)

Going to add my experience here in case it can help someone else. The upgrade to Device 3.1 as BillyMFH said changed the way tokens are created. The blog post has a lot of information in it, and the solution to the problem in this answer is a temporary one.
If config.allow_insecure_token_lookup is set to false (and once this option is deprecated), the fix in my case was to update the email views Devise uses to send out links containing tokens.
Old Devise email views contain lines like this:
<p><%= link_to 'Change my password', edit_password_url(#resource, :reset_password_token => #resource.reset_password_token) %></p>
This uses the old token stored in the DB. Now you simply do this:
<p><%= link_to 'Change my password', edit_password_url(#resource, :reset_password_token => #token) %></p>
Just replace the old token from resource with the new instance variable #token
The link in the blog post to this change is highlighted here: Devise email view token change

This likely has to do with the security updates in Devise 3.1. The token that is sent to the user does not match the one that is in the database. You could turn off this feature by including this in your devise initializer:
config.allow_insecure_token_lookup = true
But it would be best to just delete the user and create a new one with the new token system.
See this blog post about the security changes in Devise 3.1: http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/ You're
looking for the section titled "Store digested tokens in the database"

Just you need to make the following changes while you update devise or else
In following line in file app/views/devise/mailer/confirmation_instructions.html.erb
<p><%= link_to 'Confirm my account', confirmation_url(#resource, :confirmation_token => #resource.confirmation_token) %></p>
with new line as -
<p><%= link_to 'Confirm my account', confirmation_url(#resource, :confirmation_token => #token) %></p>
This will definitely solve your problem, it just work for me.
Cheers!

Related

ActionCable displays an empty page after action

I'm following Michael Hartl tutorial about Rails 5 ActionCable, to build a simple chat, and a problem is occurring inside my create action in MessageController:
def create
message = current_user.messages.build(message_params)
if message.save
ActionCable.server.broadcast 'room_channel',
content: message.content,
username: message.user.username
head :ok
end
end
It goes until head :ok, and after that, display an empty HTML page. The log is:
Processing by MessagesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"h9UsB78aX8mO8Nyn8eZEUuDzAOxL4V7UCMwNuTfwALliMv7OCkcUIeR4/xXIcvPjwq9H1bphjn6G96G+0VYisw==", "message"=>{"content"=>"oi"}, "commit"=>"Send"}
User Load (1.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
Message Load (2.1ms) SELECT "messages".* FROM "messages" ORDER BY "messages"."created_at" DESC LIMIT ? [["LIMIT", 50]]
(0.3ms) begin transaction
SQL (9.3ms) INSERT INTO "messages" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["content", "oi"], ["user_id", 1], ["created_at", 2016-09-19 02:12:58 UTC], ["updated_at", 2016-09-19 02:12:58 UTC]]
(9.1ms) commit transaction
[ActionCable] Broadcasting to room_channel: {:content=>"oi", :username=>"alice"}
Completed 200 OK in 69ms (ActiveRecord: 22.0ms)
RoomChannel transmitting {"content"=>"oi", "username"=>"alice"} (via streamed from room_channel)
Finished "/cable/" [WebSocket] for 10.0.2.2 at 2016-09-19 02:12:58 +0000
RoomChannel stopped streaming from room_channel
(After that, I can refresh the page and the message is displayed properly)
Why that is happening?
My RoomChanel class:
class RoomChannel < ApplicationCable::Channel
def subscribed
stream_from "room_channel"
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
end
My room.coffee
App.room = App.cable.subscriptions.create "RoomChannel",
connected: ->
# Called when the subscription is ready for use on the server
disconnected: ->
# Called when the subscription has been terminated by the server
received: (data) ->
alert data.content
I know the answer is accepted already, but this solution worked for me without having to remove head :ok, maybe it helps somebody out.
Normally in the development environment people are running localhost:3000 but i was running on a different port, localhost:3030.
And this case i had to add an allowed request origin for that port, like so:
config.action_cable.allowed_request_origins = [
'http://localhost:3030'
]
to my /config/environments/development.rb
Following a sugestion, I'm adding as answer what I did to get around this problem. It doesn't answer why that happens, but solve the problem.
The solution is: remove head :ok.
Aparently it's unecessary, because if I add a test whit assert_response :success to the action, it'll pass.
I'm following Michael's tutorial for ActionCable and had the same problem.
I think this was due to the format of the form partial _anything.html.erb.
app/views/messages/_message_form.html
As you go through the tutorial, you're upgrading to Action Cable features. But in the _message_form partial, it is still with the usual HTTP request. So after you broadcast a message using the messages_controller.rb, the browser render an empty page because the form was already rendered.
app/views/messages/_message_form.html, Originally:
<div class="message-input">
<%= form_for(#message) do |f| %>
<%= f.text_area :content %>
<%= f.submit "Send" %>
<% end %>
</div>
So, you have to add the remote: true to the form, like this:
<div class="message-input">
<%= form_for(#message, remote: true) do |f| %>
<%= f.text_area :content %>
<%= f.submit "Send" %>
<% end %>
</div>
Adding the remote: true makes an JS request (Ajax, in this case)
Quoting Michael:
You can verify by submitting a message that it appears as desired, but in
fact this is a cheat because the form from Listing 6 is currently submitting
an ordinary HTTP POST request, which causes the page to refresh. In order
to use Action Cable, we need to change the form to submit a remote request
that submits an Ajax request without refreshing the page. We can do this by
including the remote: true option in the call to form_for.
Note that I'm doing everything in localhost:3000

Why does Devise give me an error about being signed in for this action which surely should require being signed in?

I'm using Rails 4 with Devise. Devise comes with existing forms to set the password so I wanted to add a link for the user to change their own password once logged in.
In my view, I have:
<li><%= link_to 'Change password', edit_user_password_path %></li>
This appears to render the right link:
Change password
When I try to visit this page, I get a flash message saying "You are already signed in", and the logs show:
Started GET "/users/password/edit" for ::1 at 2016-07-05 16:46:17 +1000
Processing by Devise::PasswordsController#edit as HTML
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Redirected to http://localhost:3000/
Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 1ms (ActiveRecord: 0.1ms)
So I can see it hits the right controller and the right action, but then mysteriously redirects.
I don't really understand what this means but I would have thought that the page to edit your password would only work when signed in, so I'm not really sure why I'm getting an error about already being signed in.
Does anyone know Devise well enough to explain what's going on here?
edit_user_password_path is used for forgot password page, you need edit_user_registration_path.
Can you try to use:
edit_user_registration_path

devise_invitable not able to accept invitations anymore (but works via console)

I am using devise_invitable to create guest accounts to access a document. When accessing a document, a guest can click on an upgrade button that will upgrade to a full account. Clicking on the upgrade button is accepting devise_invitable invitation.
Was previously working: no longer working.
Environment:
rails 4.2.3 (recently upgraded)
devise 3.4.1
devise_invitable 1.3.6
I use a header partial for a guest user that generates an upgrade link:
<% #invite_link = accept_user_invitation_url(invitation_token: #invite_token) %>
<%= link_to "Upgrade", #invite_link, class: "btn btn-danger btn-lg" %>
#invite_token is created like:
user = current_user
user.invite! do |u|
u.skip_invitation = true
end
#invite_token = user.raw_invitation_token
So link_to helper generates something like: https://myapp/users/invitation/accept?invitation_token=vv_JqeFDLfyX65tx2KhR
Except when I click on the link, it takes me to: https://myapp/users/sign_in
With error message: The invitation token provided is not valid!
Log reports something like:
Started GET "/users/invitation/accept?invitation_token=vv_JqeFDLfyX65tx2KhR" for 31.15.32.222 at 2015-10-15 19:18:34 +1100
Processing by Devise::InvitationsController#edit as HTML
Parameters: {"invitation_token"=>"vv_JqeFDLfyX65tx2KhR"}
User Load (5.9ms) SELECT "users".* FROM "users" WHERE "users"."invitation_token" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["invitation_token", "ea9be9890c684e13ece13ec02f89bade81fcd3ac1fb982db72d8f8561d0cf289"]]
Redirected to https://myapp/
Filter chain halted as :resource_from_invitation_token rendered or redirected
Completed 302 Found in 53ms (ActiveRecord: 5.9ms)
Started GET "/" for 31.15.32.222 at 2015-10-15 19:49:52 +1100
Processing by PagesController#index as HTML
Redirected to https://myapp/users/sign_in
Completed 302 Found in 11ms (ActiveRecord: 0.0ms)
Am able to make this work via rails console.
If I run rails console in parallel, I am able to step through the above steps and generate an accept_invitation link that works as expected (i.e. it prompts user to set a password for the full account).
NB: the raw_invitation_token is different in the rails console session.
What am I missing?
I found code that called user.invite! to generate raw_invitation_token when page was displayed and after the accept_invitation link was generated. This meant that the token in the accept_invitation link was now outdated.
Going via the console, this code was not called as no controller, view or javascript components are invoked. So when using the console, things worked as expected.
Fixed and all back to normal.

ActionController::UnknownFormat Devise Confirmation

Whenever I have a user that has not confirmed their account, if I click on "Resend Confirmation Instructions" after putting in the correct email address, an email gets successfully sent (in development anyway) and then I get this error message:
ActionController::UnknownFormat at /users/confirmation.user
ActionController::UnknownFormat
At this URL:
http://localhost:3000/users/confirmation.user
Here is my ConfirmationsController
class ConfirmationsController < Devise::ConfirmationsController
private
def after_confirmation_path_for(resource_name, resource)
new_session_path(resource_name)
end
end
Here is the log for the entire event:
Started POST "/users/confirmation.user" for 127.0.0.1 at 2014-12-28 19:23:23 -0500
Processing by ConfirmationsController#create as
Parameters: {"utf8"=>"✓", "authenticity_token"=>"SaKoS0Xo3PEkPLDRGt0s1dDsFL3sWIGAS6TZ69bhF4E=", "user"=>{"email"=>"xyz#test.com"}, "commit"=>"Resend confirmation instructions"}
User Load (3.6ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'xyz#test.com' ORDER BY "users"."id" ASC LIMIT 1
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."confirmation_token" = '03f1df6d19e7ca7f5b3f0789e159ba3b31b24895fffc6124def25467e901b5df' ORDER BY "users"."id" ASC LIMIT 1
(1.5ms) BEGIN
SQL (14.2ms) UPDATE "users" SET "confirmation_sent_at" = $1, "confirmation_token" = $2, "updated_at" = $3 WHERE "users"."id" = 4 [["confirmation_sent_at", "2014-12-29 00:23:23.286698"], ["confirmation_token", "03f1df6d19e7ca7f5b3f0789e159ba3b31b24895fffc6124def25467e901b5df"], ["updated_at", "2014-12-29 00:23:23.296387"]]
(1.5ms) COMMIT
Rendered devise/mailer/confirmation_instructions.html.erb (0.8ms)
Devise::Mailer#confirmation_instructions: processed outbound mail in 20.1ms
Sent mail to xyz#test.com (39.6ms)
Date: Sun, 28 Dec 2014 19:23:23 -0500
From: noreply#myapp
Reply-To: noreply#myapp
To: xyz#test.com
Message-ID: <54a09efb589ec_12f63fc655865be02817a#myputer.local.mail>
Subject: Welcome to My App! Please confirm your email address
Mime-Version: 1.0
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: 7bit
<center><img alt="Logo" height="50" src="http://someurl.com/assets/logo.png" width="153" /></center>
<p>Welcome to My App, xyz#test.com! Please confirm your email address by clicking the link below:</p>
<p>Confirm my account</p>
<p>Once you confirm, you are welcomed to join the community by sharing, reading and commenting on the breaking news that matters to you.</p>
<p>Best regards,
My App</p>
Completed 406 Not Acceptable in 161ms
ActionController::UnknownFormat - ActionController::UnknownFormat:
What could be causing this?
Edit 1
Please note that this error is NOT the same as other errors. In this case, the email IS successfully sent. It is just the page/action that it is redirected to that generates the error. THAT is the issue! The issue IS NOT with what happens AFTER you press the link in the confirmations email that is sent to the user. It is what happens to the Rails app AFTER the confirmation email is successfully sent. That is why I pasted the ConfirmationsController at the top of the question, because I suspect it is central to this issue.
For re-sending the confirmation instructions (Resend Confirmation Instructions), what is the helper method you have used in your code?
It can be resolved in either of 2 solutions mentioned below:
Solution 1:
If you have used a similar one like below, please remove the parameter you have passed through it.
As per the issue reported on Github (https://github.com/plataformatec/devise/issues/2834):
In your confirmation email view you're probably passing a parameter to your url helper, something like this:
user_confirmations_url(#some_variable)
That url does not require an argument and because you are sending one, it is being set as the url format instead of replacing a url parameter.
Solution 2:
Refer this link
Hope that helps :)

RoR - Devise Confirmable email error

I'm using Ruby on Rails 3 with Devise and sending confirmation emails. The emails work correctly (as far as sending) but when I click on the Confirm my account link, it generates an error.
Can anyone shed some light, or at least point me in the right direction on what this is/how to fix this?
This is the error I see in the logs:
Started GET "/users/confirmation?confirmation_token=qKvZWHgj6ncYAyuQq3e1" for 127.0.0.1 at 2012-08-15 20:57:11 +0300
Processing by ConfirmationsController#show as HTML
Parameters: {"confirmation_token"=>"qKvZWHgj6ncYAyuQq3e1"}
User Load (9.0ms) SELECT "users".* FROM "users" WHERE "users"."confirmation_token" = 'qKvZWHgj6ncYAyuQq3e1' LIMIT 1
Completed 500 Internal Server Error in 35920ms
NoMethodError (undefined method `only_if_unconfirmed' for #):
app/controllers/confirmations_controller.rb:58:in `with_unconfirmed_confirmable'
app/controllers/confirmations_controller.rb:40:in `show'
Rendered C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-3.2.5/lib/action_dispatch/middleware/templates/rescues/_trace.erb (8.0ms)
Rendered C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-3.2.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (3.0ms)
Rendered C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-3.2.5/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (4479.3ms)
I verified that the token in the url is an exact match for this user in the db.
Probably you have a really recent version of devise, and it changed the way the confirmation token is handled, so if you generate the views with devise like so:
rails g devise:views
Then under the app/views/devise/mailer/confirmation_instructions.html.erb file you have something like:
....
<%= link_to 'Confirm my account', confirmation_url(#resource, :confirmation_token => #resource.confirmation_token) %>
....
You should change that for:
<%= link_to 'Confirm my account', confirmation_url(#resource, :confirmation_token => #token) %>
As you can see they use an instance variable called #token instead of #resource.confirmation_token
That should do the trick!

Resources