4

J'utilise Rails-api pour créer une application d'authentification de test qui utilise Devise_token_auth gem. Le modèle User.rb ressembleParamètre non autorisé utilisant la gemme Devise Token Auth dans l'API Rails

class User < ActiveRecord::Base 
    before_save :set_auth_token 

    # Include default devise modules. 
    devise :database_authenticatable, :registerable, 
      :recoverable, :rememberable, :trackable, :validatable, 
      :confirmable, :omniauthable 
    include DeviseTokenAuth::Concerns::User 

    private 
    def set_auth_token 
    if self.authentication_token.blank? 
     self.authentication_token = generate_authentication_token 
    end 
    end 

    def generate_authentication_token 
    loop do 
     token = Devise.friendly_token 
     break token unless User.where(authentication_token: token).first 
    end 
    end 

end 

routes.rb contient

mount_devise_token_auth_for 'User', at: 'auth' 

J'utilise aussi la valeur par défaut SessionsController et RegistrationsController défini par DeviseTokenAuth bijou

Mon frontend est faite en Ember-cli où j'ai fait un formulaire de connexion qui utilise Ember-simple-auth-devise, Devise authorizer pour appeler le/sign_in l de rails api. Le Ember simple, enveloppe auth les paramètres tels que

{"user"=>{"password"=>"[FILTERED]", "email"=>"[email protected]"}} 

tandis que les rails DeviseTokenAuth attend des paramètres de la requête comme

{"password"=>"[FILTERED]", "email"=>"[email protected]"} 

L'erreur produite est

Processing by DeviseTokenAuth::RegistrationsController#create as JSON 
    Parameters: {"user"=>{"password"=>"[FILTERED]", "email"=>"[email protected]"}} 
Unpermitted parameter: user 

Le problème peut être résolu si soit Rails DeviseTokenAuth gem accepte les paramètres enveloppés dans "utilisateur" OU Ember-simple-auth envoie les paramètres déballés, mais malheureusement la documentation pour les deux ne mentionne pas clairement la façon de mettre en œuvre la même chose. Je essayé de changer le resourceName pour Ember-simple-auth null, mais ça n'a pas

ENV['simple-auth-devise'] = { 
    resourceName: null, 
    serverTokenEndpoint: 'http://localhost:3000/auth/sign_in' 
    }; 

est-il un moyen d'envoyer des paramètres non emballé dans Ember-simple-auth-concevoir? Ou est-il possible d'autoriser les paramètres contenus dans "user" pour tous les contrôleurs générés à l'aide de DeviseTokenAuth gem?

Versions utilisées sont:

devise_token_auth (0.1.36) 
    devise (~> 3.5.2) 
    rails (~> 4.2) 
"ember-simple-auth": "0.8.0" 
+0

Je pense que vous allez avoir à utiliser-auth Ember-simple, sans le plugin DEVISE et roulez vous-même. On dirait que le plugin spécifique à la vanille. – penner

+0

Numéro Github https://github.com/lynndylanhurley/devise_token_auth/issues/822 –

Répondre

1

Une solution consiste à étendre ember-simple-auth/addon/authenticators/devise.js comme cela se fait here.


En app/authenticators/devise.js, REPLACE:

import Devise from 'ember-simple-auth/authenticators/devise'; 

export default Devise.extend({}); 

par:

import Ember from 'ember'; 
import Devise from 'ember-simple-auth/authenticators/devise'; 

const { RSVP: { Promise }, isEmpty, getProperties, run, get } = Ember; 

export default Devise.extend({ 
    loginEndpoint: '/auth/sign_in', 
    logoutEndpoint: '/auth/sign_out', 

    authenticate(identification, password) { 
    return new Promise((resolve, reject) => { 
     let { identificationAttributeName } = getProperties(this, 'identificationAttributeName'); 
     let data = { password }; 
     data[identificationAttributeName] = identification; 

     let requestOptions = { url: get(this, 'loginEndpoint') }; 

     this.makeRequest(data, requestOptions).then((response) => { 
     if (response.ok) { 
      response.json().then((json) => { 
      let data = { 
       account: json, 
       accessToken: response.headers.get('access-token'), 
       expiry: response.headers.get('expiry'), 
       tokenType: response.headers.get('token-type'), 
       uid: response.headers.get('uid'), 
       client: response.headers.get('client') 
      }; 

      if (this._validate(data)) { 
       run(null, resolve, data); 
      } else { 
       run(null, reject, 'Check that server response header includes data token and valid.'); 
      } 
      }); 
     } else { 
      response.json().then((json) => run(null, reject, json)); 
     } 
     }).catch((error) => run(null, reject, error)); 
    }); 
    }, 

    invalidate(data) { 
    return new Promise((resolve, reject) => { 
     let headers = { 
     'access-token': data.accessToken, 
     'expiry': data.expiry, 
     'token-type': data.tokenType, 
     'uid': data.uid, 
     'client': data.client 
     }; 

     let requestOptions = { 
     url: get(this, 'logoutEndpoint'), 
     method: 'DELETE', 
     headers 
     }; 

     this.makeRequest({}, requestOptions).then((response) => { 
     response.json().then((json) => { 
      if (response.ok) { 
      run(null, resolve, json); 
      } else { 
      run(null, reject, json); 
      } 
     }); 
     }).catch((error) => run(null, reject, error)); 
    }); 
    }, 

    _validate(data) { 
    let now = (new Date()).getTime(); 

    return !isEmpty(data.accessToken) && !isEmpty(data.expiry) && (data.expiry * 1000 > now) && 
     !isEmpty(data.tokenType) && !isEmpty(data.uid) && !isEmpty(data.client); 
    } 
});