Confirmation token gets updated when using after_create hook, and confirmation link doesn't work

217 views
Skip to first unread message

Anton Bogdanovich

unread,
Sep 30, 2014, 7:17:20 PM9/30/14
to plataforma...@googlegroups.com
Using Devise 3.3.0, Rails 4.1.6

The same thing was described here: https://github.com/plataformatec/devise/issues/2706

I'm using after_create hook, because i need user.id to generate access_token.

Here is my model:

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable

  after_create :init_access_token

  def init_access_token
     hashids = Hashids.new(Rails.application.secrets.access_token_salt, Rails.configuration.access_token[:min_size])
     update(access_token: hashids.encode(self.id, 0))
  end
end

It seems, Devise generates new confirmation token with second save.
Is there workaround? Or it's a known bug?
How to update record before user confirmed his email? 

Here is console example:

2.1.3 :001 > u = User.create(email: "te...@test.com", password: "qweqweqweqwe")
   (0.2ms)  begin transaction
  User Exists (0.2ms)  SELECT  1 AS one FROM "users"  WHERE "users"."email" = 'te...@test.com' LIMIT 1
  User Exists (0.1ms)  SELECT  1 AS one FROM "users"  WHERE "users"."email" = 'te...@test.com' LIMIT 1

DEVISE TOKEN GENERATE (DEBUG): 
"Q\x1Ck\x14l*\"\xDAr\xC4\x98i\xA6\xC0f\xF6\xD4\x82\xAFD\xF96\x87\x92v\xD8\xFDG{\xEE\x00\xE6\xD8*\xE8\ep\xC1C\xDFM\xC3\xA8un\x86%\xB8\xBA\xD6\xE4\xBC\x11\xBE7Z3\x14\xB9.\x1E\xEF\x92\x13"

  User Load (0.2ms)  SELECT  "users".* FROM "users"  WHERE "users"."confirmation_token" = '695953bb2e24ba6757007e63ffa360f59b44d13f1a73cadfb5fd4d6dfbb82e74'  ORDER BY "users"."id" ASC LIMIT 1
Binary data inserted for `string` type on column `confirmation_token`
Binary data inserted for `string` type on column `encrypted_password`
  SQL (0.5ms)  INSERT INTO "users" ("confirmation_sent_at", "confirmation_token", "created_at", "email", "encrypted_password", "updated_at") VALUES (?, ?, ?, ?, ?, ?)  [["confirmation_sent_at", "2014-09-30 23:09:46.383358"], ["confirmation_token", "695953bb2e24ba6757007e63ffa360f59b44d13f1a73cadfb5fd4d6dfbb82e74"], ["created_at", "2014-09-30 23:09:46.176443"], ["email", "te...@test.com"], ["encrypted_password", "$2a$10$ImriP7aVgwESJsYy1nUTNOSqho3xs8XAn6A0ETgGblI0NqiResNdG"], ["updated_at", "2014-09-30 23:09:46.176443"]]
  Rendered devise/mailer/confirmation_instructions.html.erb (2.7ms)

Devise::Mailer#confirmation_instructions: processed outbound mail in 21.9ms

Sent mail to te...@test.com (2784.3ms)
Date: Tue, 30 Sep 2014 16:09:46 -0700
Reply-To: so...@email.com
Message-ID: <542b383a66a72_de1d9b32c70372@mail>
Subject: Confirmation instructions
Mime-Version: 1.0
Content-Type: text/html;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

<p>Welcome te...@test.com!</p>

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


#<User id: 3, email: "te...@test.com", role: 0, access_token: nil, plan_id: nil, effective_date: nil, created_at: "2014-09-30 23:09:46", updated_at: "2014-09-30 23:09:46", encrypted_password: "$2a$10$ImriP7aVgwESJsYy1nUTNOSqho3xs8XAn6A0ETgGblI...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, confirmation_token: "695953bb2e24ba6757007e63ffa360f59b44d13f1a73cadfb5...", confirmed_at: nil, confirmation_sent_at: "2014-09-30 23:09:46", unconfirmed_email: nil>
  User Exists (0.3ms)  SELECT  1 AS one FROM "users"  WHERE ("users"."email" = 'te...@test.com' AND "users"."id" != 3) LIMIT 1
  User Exists (0.2ms)  SELECT  1 AS one FROM "users"  WHERE ("users"."email" = 'te...@test.com' AND "users"."id" != 3) LIMIT 1

DEVISE TOKEN GENERATE (DEBUG): 
"Q\x1Ck\x14l*\"\xDAr\xC4\x98i\xA6\xC0f\xF6\xD4\x82\xAFD\xF96\x87\x92v\xD8\xFDG{\xEE\x00\xE6\xD8*\xE8\ep\xC1C\xDFM\xC3\xA8un\x86%\xB8\xBA\xD6\xE4\xBC\x11\xBE7Z3\x14\xB9.\x1E\xEF\x92\x13"

  User Load (0.3ms)  SELECT  "users".* FROM "users"  WHERE "users"."confirmation_token" = '924e5eabf7436a66453e8c2a526214ab6c01205b6141d2d9632b434eb1ae6711'  ORDER BY "users"."id" ASC LIMIT 1
Binary data inserted for `string` type on column `confirmation_token`
Binary data inserted for `string` type on column `encrypted_password`
  SQL (0.6ms)  UPDATE "users" SET "access_token" = ?, "confirmation_sent_at" = ?, "confirmation_token" = ?, "created_at" = ?, "encrypted_password" = ?, "id" = ?, "unconfirmed_email" = ?, "updated_at" = ? WHERE "users"."id" = 3  [["access_token", "jP9xZys2Vwzb"], ["confirmation_sent_at", "2014-09-30 23:09:49.210273"], ["confirmation_token", "924e5eabf7436a66453e8c2a526214ab6c01205b6141d2d9632b434eb1ae6711"], ["created_at", "2014-09-30 23:09:46.176443"], ["encrypted_password", "$2a$10$ImriP7aVgwESJsYy1nUTNOSqho3xs8XAn6A0ETgGblI0NqiResNdG"], ["id", 3], ["unconfirmed_email", "te...@test.com"], ["updated_at", "2014-09-30 23:09:46.176443"]]
   (13.6ms)  commit transaction
 => #<User id: 3, email: "", role: 0, access_token: "jP9xZys2Vwzb", plan_id: nil, effective_date: nil, created_at: "2014-09-30 23:09:46", updated_at: "2014-09-30 23:09:46", encrypted_password: "$2a$10$ImriP7aVgwESJsYy1nUTNOSqho3xs8XAn6A0ETgGblI...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, confirmation_token: "924e5eabf7436a66453e8c2a526214ab6c01205b6141d2d963...", confirmed_at: nil, confirmation_sent_at: "2014-09-30 23:09:49", unconfirmed_email: "te...@test.com"> 




Lucas Mazza

unread,
Oct 6, 2014, 12:53:45 PM10/6/14
to plataforma...@googlegroups.com
Anton, do you have a sample application for this behaviour? Looks like something in the middle of these callbacks is mutating too much state of the object that it is generating one token in the 'before_*' callback and another in the 'after_*' callbacks. If we put an app running with this behaviour I could take a look and see what is going on.

--

---
You received this message because you are subscribed to the Google Groups "Devise" group.
To unsubscribe from this group and stop receiving emails from it, send an email to plataformatec-de...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Anton Bogdanovich

unread,
Oct 6, 2014, 4:07:53 PM10/6/14
to plataforma...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages