Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POST with JSON Content-Type: application/json not passing parameters #1221

Closed
cdesch opened this issue Oct 1, 2018 · 3 comments
Closed

POST with JSON Content-Type: application/json not passing parameters #1221

cdesch opened this issue Oct 1, 2018 · 3 comments

Comments

@cdesch
Copy link

cdesch commented Oct 1, 2018

The issue is that when post a json to sign_in path, the email and password do not get passed along.

e.g. this gets put in, curl -XPOST -H 'Content-Type: application/json' http://localhost:3000/api/v1/auth/sign_in -d '{"email": "[email protected]", "password": "password" }'

And this is the rails console:

Started POST "/api/v1/auth/sign_in" for 127.0.0.1 at 2018-10-01 17:31:05 -0400
Processing by Overrides::SessionsController#create as */*
<ActionController::Parameters {"controller"=>"overrides/sessions", "action"=>"create"} permitted: false>
<ActionController::Parameters {"controller"=>"overrides/sessions", "action"=>"create"} permitted: false>
{}
<ActionController::Parameters {"controller"=>"overrides/sessions", "action"=>"create"} permitted: false>
Completed 401 Unauthorized in 2ms (Views: 0.3ms | ActiveRecord: 0.0ms)

It will take 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', as i have successfully used j-toker with it. Why wont the json post work?

I did override the Devise Session Controller, although that was only to debug the params coming into devise.

  • Version: devise_token_auth (0.2.0) and redux-token-auth

  • Request and response headers:
    curl -XPOST -H 'Content-Type: application/json' http://localhost:3000/api/v1/auth/sign_in -d '{"email": "[email protected]", "password": "password" }'

  • Environmental Info: Using Devise and Devise Token Auth together

    • Routes: are you using some crazy namespace, scope, or constraint?
  devise_for :users , path: 'auth'
  ActiveAdmin.routes(self)

  namespace :api do
    scope :v1 do
      mount_devise_token_auth_for 'User', at: 'auth', controllers: {
          sessions: 'overrides/sessions'
      }
    end
  end

  • Gems: ActiveAdmin, Devise
  • Custom Overrides:
module Overrides
  class SessionsController < DeviseTokenAuth::SessionsController
    skip_before_action :verify_authenticity_token

    before_action :set_user_by_token, only: [:destroy]
    after_action :reset_session, only: [:destroy]

    def new
      render_new_error
    end

    def create
      puts params.inspect
      puts resource_params
      # Check
      field = (resource_params.keys.map(&:to_sym) & resource_class.authentication_keys).first

      @resource = nil
      if field
        q_value = get_case_insensitive_field_from_resource_params(field)
        puts q_value
        puts field
        @resource = find_resource(field, q_value)
      end

      if @resource && valid_params?(field, q_value) && ([email protected]_to?(:active_for_authentication?) || @resource.active_for_authentication?)
        valid_password = @resource.valid_password?(resource_params[:password])
        if (@resource.respond_to?(:valid_for_authentication?) && [email protected]_for_authentication? { valid_password }) || !valid_password
          return render_create_error_bad_credentials
        end
        @client_id, @token = @resource.create_token
        @resource.save

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

        yield @resource if block_given?

        render_create_success
      elsif @resource && !([email protected]_to?(:active_for_authentication?) || @resource.active_for_authentication?)
        if @resource.respond_to?(:locked_at) && @resource.locked_at
          render_create_error_account_locked
        else
          render_create_error_not_confirmed
        end
      else
        render_create_error_bad_credentials
      end
    end

    def destroy
      # remove auth instance variables so that after_action does not run
      user = remove_instance_variable(:@resource) if @resource
      client_id = remove_instance_variable(:@client_id) if @client_id
      remove_instance_variable(:@token) if @token

      if user && client_id && user.tokens[client_id]
        user.tokens.delete(client_id)
        user.save!

        yield user if block_given?

        render_destroy_success
      else
        render_destroy_error
      end
    end

    protected

    def valid_params?(key, val)
      resource_params[:password] && key && val
    end

    def get_auth_params
      auth_key = nil
      auth_val = nil

      # iterate thru allowed auth keys, use first found
      resource_class.authentication_keys.each do |k|
        if resource_params[k]
          auth_val = resource_params[k]
          auth_key = k
          break
        end
      end

      # honor devise configuration for case_insensitive_keys
      if resource_class.case_insensitive_keys.include?(auth_key)
        auth_val.downcase!
      end

      { key: auth_key, val: auth_val }
    end

    def render_new_error
      render_error(405, I18n.t('devise_token_auth.sessions.not_supported'))
    end

    def render_create_success
      render json: {
          data: resource_data(resource_json: @resource.token_validation_response)
      }
    end

    def render_create_error_not_confirmed
      render_error(401, I18n.t('devise_token_auth.sessions.not_confirmed', email: @resource.email))
    end

    def render_create_error_account_locked
      render_error(401, I18n.t('devise.mailer.unlock_instructions.account_lock_msg'))
    end

    def render_create_error_bad_credentials
      render_error(401, I18n.t('devise_token_auth.sessions.bad_credentials'))
    end

    def render_destroy_success
      render json: {
          success:true
      }, status: 200
    end

    def render_destroy_error
      render_error(404, I18n.t('devise_token_auth.sessions.user_not_found'))
    end

    private

    def resource_params
      puts params.inspect
      params.permit(*params_for_resource(:sign_in))
    end



  end
end
  • Custom Frontend: redux-token-auth

Other relevant files:

#controllers/application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception, if: :verify_api

  def verify_api
    puts params
    params[:controller].split('/')[0] != 'devise_token_auth'
  end

end

#controllers/api/v1/application_controller.rb

module Api
  module V1
    class ApplicationController < ::ApplicationController
      skip_before_action :verify_authenticity_token
      include DeviseTokenAuth::Concerns::SetUserByToken

    end
  end
end

#controllers/api_controller.rb
(for the rest of the controllers in controllers/api/v1

class ApiController < ActionController::Base
  
end

Issue #142 seems to be similar.

In summary, I'm trying to use devise_token_auth with redux-token-auth. When redux-token-auth performs it's post signInUser Axios post, the params ({"email":"[email protected]","password":"password"}: ) get dropped or cleaned some how before they reach the devise controller. In trying to troubleshoot what is going on, it is expected that the devise controller will authenticate but does not.

I have successfully test authentication with j-toker but that uses a different content-type of form to POST to the API.

There are some environmental differences because I am using devise with devise-toke-auth, which may be a source of a problem somewhere.

@cdesch cdesch changed the title Post with Json POST with JSON Content-Type: application/json not passing parameters Oct 1, 2018
@MaicolBen
Copy link
Collaborator

@cdesch You have to wrap it inside user, sorry for the delay!

@cdesch
Copy link
Author

cdesch commented Oct 25, 2018

e.g. { "user": {"email": "[email protected]", "password": "password" }} ?

@MaicolBen
Copy link
Collaborator

@cdesch yeah!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants