【问题标题】:Unpermitted parameter using Devise Token Auth gem in Rails API在 Rails API 中使用 Devise Token Auth gem 的未经许可的参数
【发布时间】:2016-01-21 00:20:55
【问题描述】:

我正在使用 Rails-api 制作一个使用 Devise_token_auth gem 的测试身份验证应用程序。 User.rb 模型看起来像

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 包含

mount_devise_token_auth_for 'User', at: 'auth'

我也在使用 DeviseTokenAuth gem 定义的默认 SessionsController 和 RegistrationsController

我的前端是在 Ember-cli 中制作的,在那里我制作了一个使用 Ember-simple-auth-devise 的登录表单,设计授权者调用 rails api 的 /sign_in url。 Ember 简单身份验证包装了类似的参数

{"user"=>{"password"=>"[FILTERED]", "email"=>"test@mail.com"}}

而 rails DeviseTokenAuth 需要像这样的请求参数

{"password"=>"[FILTERED]", "email"=>"test@mail.com"}

产生的错误是

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

如果 Rails DeviseTokenAuth gem 接受包装在“用户”中的参数或 Ember-simple-auth 发送未包装的参数,则问题可以解决,但不幸的是,两者的文档都没有明确提及实现相同的方法。 我尝试将 Ember-simple-auth 的 resourceName 更改为 null,但没有成功

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

有没有办法在 Ember-simple-auth-devise 中发送解包参数? 或者是否可以允许使用 DeviseTokenAuth gem 生成的所有控制器的“用户”中包含的参数?

使用的版本是:

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

【问题讨论】:

标签: javascript ruby-on-rails ember.js devise ember-simple-auth


【解决方案1】:

一种解决方案是像 here 一样扩展 ember-simple-auth/addon/authenticators/devise.js


app/authenticators/devise.js 中,替换:

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

export default Devise.extend({});

作者:

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);
  }
});

【讨论】:

    猜你喜欢
    • 2013-06-27
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多