J'essaie de migrer une tonne d'utilisateurs d'une ancienne base de données. Pour ce faire, j'utilise activerecord-import et j'essaie de sauvegarder toutes mes données utilisateur directement dans DB (en contournant le modèle utilisateur).
Mon problème: je dois prendre le mot de passe en texte brut de l'ancien utilisateur, le chiffrer et le stocker directement dans la base de données. Je sais comment générer un mot de passe à l'aide de Devise, mais je me demande s'il existe un moyen d'obtenir un mot de passe haché que je puisse stocker directement dans la base de données.
En espérant faire:
new_hashed_password = Devise.awesome_encrypting_method(old_user.password)
Enregistrez ensuite "new_hashed_password" directement dans la base de données sans passer par le modèle. J'ai fouillé dans Devise et j'ai trouvé ceci:
def password_digest(password)
::BCrypt::Password.create("#{password}#{self.class.pepper}", :cost => self.class.stretches).to_s
end
@@ s'étire par défaut à 10 (lib/devise.rb: 71) et n'est pas remplacé par mon initialiseur
@@ pepper par défaut à nil (lib/devise.rb: 148) et n'est pas remplacé par mon initialiseur
Je pensais pouvoir recréer manuellement password_digest () mais je pense que je manque quelque chose de fondamental à propos de Bcrypt car même avec la définition du mot de passe et des étirements, le hachage résultant est différent à chaque fois.
Des idées? Merci de votre aide!
De bonnes nouvelles et de mauvaises nouvelles.
Les opérations suivantes permettent de créer manuellement le mot de passe de votre utilisateur.
pepper = nil
cost = 10
encrypted_password = ::BCrypt::Password.create("#{password}#{pepper}", :cost => cost).to_s
Vous pouvez trouver votre poivre et son coût dans votre initialiseur de devise. Cette méthode a été confirmée à l'aide de "valid_password?" De Devise méthode.
La raison pour laquelle j'essayais d'éviter "User.new (mot de passe: mot de passe) .encrypted_password" était due à la vitesse. C'est terriblement lent. Avec toutes mes autres pièces de ma tâche d'importation, j'ai intentionnellement évité cela.
Mais il s'avère que le coût principal ici n'est pas l'instanciation d'un objet utilisateur - mais BCrypt lui-même. Il y a très peu d'augmentation notable de la vitesse lors de l'utilisation directe de BCrypt car il est intentionnellement conçu pour être lent.
Ma réponse finale: sucer, exécuter le script de râteau, aller chercher une boisson.
Vous devez le faire comme ceci:
password = 'the secret password'
new_hashed_password = User.new(:password => password).encrypted_password
C'est beaucoup mieux que d'utiliser BCrypt directement car il résume la façon dont les mots de passe sont générés à partir de votre code, ce qui le rend plus facile à comprendre et également à l'abri des changements dans la façon dont le concept construit des mots de passe cryptés. Votre code ne devrait pas et n'a aucune raison de savoir quoi que ce soit à ce sujet.
Aucune des autres réponses ci-dessus n'a fonctionné pour moi, alors voici ce que j'ai fait:
user.valid_password?(plain_password)
Une autre méthode est la suivante: User.new.send(:password_digest, 'xxx')
En supposant que vous avez une base de données mysql avec une table "utilisateurs" et une colonne "mot de passe" Et une classe de modèle ActiveRecord appelée "utilisateur" qui est connectée pour concevoir
Créez une classe de modèle ActiveRecord dans votre application app/models/old_user.rb
OldUser < ActiveRecord::Base
set_table :users
establish_connection :database => "old_database", :user => "old user", :adapter => "mysql"
end
puis créez une tâche de râteau: app/lib/tasks/migrate_users.rake
task :migrate_users => :environment do
OldUser.find_each do |old_user|
u = User.new(:email => old_user.email, :password => old_user.password, :password_confirmation => old_user.password);
#if your using confirmation
u.skip_confirmation!
u.save!
end
end
Modifiez si nécessaire (assurez-vous que vous enregistrez les attributs utilisateur spécifiques à l'application)
Alors$ rake migrate_users