6

Je suis en train de se connecter à un utilisateur existant en utilisant la version devise_token_auth0.1.38, mais je frappe un IndexError: string not matched dans sessions_controller de la bibliothèque.devise_token_auth & Rails 5 - IndexError: string ne correspondent pas

IndexError (string not matched): 

devise_token_auth (0.1.38) app/controllers/devise_token_auth/sessions_controller.rb:37:in `[]=' 
devise_token_auth (0.1.38) app/controllers/devise_token_auth/sessions_controller.rb:37:in `create' 
actionpack (5.0.0) lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action' 
actionpack (5.0.0) lib/abstract_controller/base.rb:188:in `process_action' 
actionpack (5.0.0) lib/action_controller/metal/rendering.rb:30:in `process_action' 
actionpack (5.0.0) lib/abstract_controller/callbacks.rb:20:in `block in process_action' 

Le code correspondant de sessions_controller est:

if @resource and valid_params?(field, q_value) and @resource.valid_password?(resource_params[:password]) and ([email protected]_to?(:active_for_authentication?) or @resource.active_for_authentication?) 
    # create client id 
    @client_id = SecureRandom.urlsafe_base64(nil, false) 
    @token  = SecureRandom.urlsafe_base64(nil, false) 

    # !! Next line is line 37 with the error !! 
    @resource.tokens[@client_id] = { 
     token: BCrypt::Password.create(@token), 
     expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i 
    } 
    @resource.save 

    sign_in(:user, @resource, store: false, bypass: false) 

J'ai ajouté devise_token_auth à un projet existant il est donc très possible que j'ai créé de mauvaises données dans la colonne tokens. J'ai essayé plusieurs façons de par défaut token json dans mes utilisateurs existants, y compris en imitant le code dans le sessions_controller.

add_column :users, :tokens, :json, null: false, default: {} 

User.reset_column_information 
client_id = SecureRandom.urlsafe_base64(nil, false) 
token  = SecureRandom.urlsafe_base64(nil, false) 

User.find_each do |user| 
    user.uid = user.email 
    user.provider = 'email' 
    user.tokens[client_id] = { 
     token: BCrypt::Password.create(token), 
     expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i 
    } 
    user.save! 
end 

Je l'ai vu une mention dans issue #101, mais cela n'a pas une résolution spécifique. Une idée d'où je vais mal?

+0

Pour moi, cela semble seulement se produire lorsque je lance mon application rails sur Heroku. Mon instance locale n'a pas ce problème. J'ai remarqué que ma version Postgres (9.6.2) différait localement de la version Heroku (9.6.4). Je ne sais pas si cela cause le problème ou non –

Répondre

4

Il s'avère que je devais régler le tokens à nil, puis concevoir prendra soin de régler cela pour moi. J'ai trouvé la réponse dans this devise issue.

def change 
    add_column :users, :provider, :string, null: false, default: "email" 
    add_column :users, :uid, :string, null: false, default: "" 
    add_column :users, :tokens, :text 

    reversible do |direction| 
    direction.up do 
     User.find_each do |user| 
     user.uid = user.email 
     user.tokens = nil 
     user.save! 
     end 
    end 
    end 

    add_index :users, [:uid, :provider], unique: true 
end