So I'm trying to right a recover password mechanism for my rails api and I've hit a wall.
After doing some research, I came up with a way to implement it. It returns the values like it work but the password does not get reset and I don't why.
My user table looks like this:
create_table "users", force: :cascade do |t|
t.string "first_name"
t.string "middle_name"
t.string "last_name"
t.string "username"
t.string "email"
t.string "password_digest"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
end
And my way of resetting the password goes: From controller:
...
def reset
token = params[:token].to_s
if params[:email].blank?
return render json: {error: 'Token not present.'}
end
user = User.find_by(reset_password_token: token)
if user.present? && user.password_token_valid?
if user.reset_password!(params[:password])
render json: {status: 'ok'}, status: :ok
else
render json: {error: user.errors.full_messages}, status: :unprocessable_entity
end
else
render json: {error: 'Link not valid or expired.'}, status: :not_found
end
end
...
Then model:
...
def password_token_valid?
(self.reset_password_sent_at + 4.hours) > Time.now.utc
end
def reset_password!(password)
self.reset_password_token = nil
self.password = password
end
...
Is this the right way to implement this? Is this the safest way to implement this?
Note: I only tested this on production, this is due to the limitation of my development environment to send emails.
You're just updating the values in memory and never persisting them to the database.
def reset_password!(password)
update!(
password: password,
reset_password_token: nil
)
end
Is this the safest way to implement this?
No. Reinventing the authentication wheel is one of the most common reason apps get hacked.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다