Как аутентифицироваться с Android ... Knock + Ruby api с использованием библиотеки залпа ... выдает ошибку (параметр отсутствует или значение пусто: auth): - PullRequest
0 голосов
/ 29 октября 2019

Я следовал этому учебнику

Все отлично работает, когда я использую почтальон. Однако, когда я попытался использовать библиотеку залпов для аутентификации из моего приложения для Android, она выдает следующую ошибку. Я подозреваю, как я посылаю полезную нагрузку или заголовки. Как должен выглядеть мой заголовок для выполнения аутентификации?

ActionController :: ParameterMissing (параметр отсутствует или значение пусто: auth):

actionpack (5.2.3) lib/action_controller/metal/strong_parameters.rb:443:in `require'
knock (2.1.1) app/controllers/knock/auth_token_controller.rb:44:in `auth_params'
knock (2.1.1) app/controllers/knock/auth_token_controller.rb:31:in `entity'
knock (2.1.1) app/controllers/knock/auth_token_controller.rb:13:in `authenticate'
activesupport (5.2.3) lib/active_support/callbacks.rb:426:in `block in make_lambda'
activesupport (5.2.3) lib/active_support/callbacks.rb:198:in `block (2 levels) in halting'
actionpack (5.2.3) lib/abstract_controller/callbacks.rb:34:in `block (2 levels) in <module:Callbacks>'
activesupport (5.2.3) lib/active_support/callbacks.rb:199:in `block in halting'
activesupport (5.2.3) lib/active_support/callbacks.rb:513:in `block in invoke_before'
activesupport (5.2.3) lib/active_support/callbacks.rb:513:in `each'
activesupport (5.2.3) lib/active_support/callbacks.rb:513:in `invoke_before'
activesupport (5.2.3) lib/active_support/callbacks.rb:131:in `run_callbacks'
actionpack (5.2.3) lib/abstract_controller/callbacks.rb:41:in `process_action'
actionpack (5.2.3) lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack (5.2.3) lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'
activesupport (5.2.3) lib/active_support/notifications.rb:168:in `block in instrument'
activesupport (5.2.3) lib/active_support/notifications/instrumenter.rb:23:in `instrument'
activesupport (5.2.3) lib/active_support/notifications.rb:168:in `instrument'
actionpack (5.2.3) lib/action_controller/metal/instrumentation.rb:32:in `process_action'
actionpack (5.2.3) lib/action_controller/metal/params_wrapper.rb:256:in `process_action'
activerecord (5.2.3) lib/active_record/railties/controller_runtime.rb:24:in `process_action'
actionpack (5.2.3) lib/abstract_controller/base.rb:134:in `process'
actionview (5.2.3) lib/action_view/rendering.rb:32:in `process'
actionpack (5.2.3) lib/action_controller/metal.rb:191:in `dispatch'
actionpack (5.2.3) lib/action_controller/metal.rb:252:in `dispatch'
actionpack (5.2.3) lib/action_dispatch/routing/route_set.rb:52:in `dispatch'
actionpack (5.2.3) lib/action_dispatch/routing/route_set.rb:34:in `serve'
actionpack (5.2.3) lib/action_dispatch/journey/router.rb:52:in `block in serve'
actionpack (5.2.3) lib/action_dispatch/journey/router.rb:35:in `each'
actionpack (5.2.3) lib/action_dispatch/journey/router.rb:35:in `serve'
actionpack (5.2.3) lib/action_dispatch/routing/route_set.rb:840:in `call'
rack (2.0.7) lib/rack/etag.rb:25:in `call'
rack (2.0.7) lib/rack/conditional_get.rb:38:in `call'
rack (2.0.7) lib/rack/head.rb:12:in `call'
activerecord (5.2.3) lib/active_record/migration.rb:559:in `call'
actionpack (5.2.3) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
activesupport (5.2.3) lib/active_support/callbacks.rb:98:in `run_callbacks'
actionpack (5.2.3) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (5.2.3) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (5.2.3) lib/action_dispatch/middleware/debug_exceptions.rb:61:in `call'
actionpack (5.2.3) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (5.2.3) lib/rails/rack/logger.rb:38:in `call_app'
railties (5.2.3) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (5.2.3) lib/active_support/tagged_logging.rb:71:in `block in 
 tagged'
activesupport (5.2.3) lib/active_support/tagged_logging.rb:28:in `tagged'
activesupport (5.2.3) lib/active_support/tagged_logging.rb:71:in `tagged'
railties (5.2.3) lib/rails/rack/logger.rb:26:in `call'
actionpack (5.2.3) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (5.2.3) lib/action_dispatch/middleware/request_id.rb:27:in `call'
 rack (2.0.7) lib/rack/runtime.rb:22:in `call'
activesupport (5.2.3) 
lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
 actionpack (5.2.3) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (5.2.3) lib/action_dispatch/middleware/static.rb:127:in `call'
rack (2.0.7) lib/rack/sendfile.rb:111:in `call'
railties (5.2.3) lib/rails/engine.rb:524:in `call'
puma (3.12.1) lib/puma/configuration.rb:227:in `call'
puma (3.12.1) lib/puma/server.rb:660:in `handle_request'
puma (3.12.1) lib/puma/server.rb:474:in `process_client'
puma (3.12.1) lib/puma/server.rb:334:in `block in run'
puma (3.12.1) lib/puma/thread_pool.rb:135:in `block in spawn_thread'

Мой код Android. Примечание: я использовал method1 и method2 отдельно, и объединил, но та же самая ошибка

public class Main2Activity extends AppCompatActivity {

// Creating EditText.
EditText Email, Password;

// Creating button;
Button LoginButton;

// Creating Volley RequestQueue.
RequestQueue requestQueue;

// Create string variable to hold the EditText Value.
String EmailHolder, PasswordHolder;

// Creating Progress dialog.
ProgressDialog progressDialog;

// Storing server url into String variable.
String HttpUrl = "http://10.0.2.2:3000/user_token";


Boolean CheckEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);

    // Assigning ID's to EditText.
    Email = findViewById(R.id.editText_Email);

    Password = findViewById(R.id.editText_Password);

    // Assigning ID's to Button.
    LoginButton = findViewById(R.id.button_login);

    // Creating Volley newRequestQueue .
    requestQueue = Volley.newRequestQueue(Main2Activity.this);

    // Assigning Activity this to progress dialog.
    progressDialog = new ProgressDialog(Main2Activity.this);

    // Adding click listener to button.
    LoginButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            CheckEditTextIsEmptyOrNot();

            if (CheckEditText) {

                UserLogin();

            } else {

                Toast.makeText(Main2Activity.this, "Please fill all form fields.", Toast.LENGTH_LONG).show();

            }

        }
    });

}

// Creating user login function.
public void UserLogin() {

    // Showing progress dialog at user registration time.
    progressDialog.setMessage("Please Wait");
    progressDialog.show();

    // Creating string request with post method.
    StringRequest stringRequest = new StringRequest(Request.Method.POST, HttpUrl,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String ServerResponse) {

                    Log.d("onResponse", ServerResponse);
                    // Hiding the progress dialog after all task complete.
                    progressDialog.dismiss();

                    // Matching server responce message to our text.
                    if(ServerResponse.equals("200")) {

                        // If response matched then show the toast.
                        Toast.makeText(Main2Activity.this, "Logged In Successfully", Toast.LENGTH_LONG).show();

                        // Finish the current Login activity.
                        finish();

                        // Opening the user profile activity using intent.
                        Intent intent = new Intent(Main2Activity.this, ProfileActivity.class);

                        // Sending User Email to another activity using intent.
                        intent.putExtra("UserEmailTAG", EmailHolder);

                        startActivity(intent);
                    }
                    else {

                        // Showing Echo Response Message Coming From Server.
                        Toast.makeText(Main2Activity.this, ServerResponse, Toast.LENGTH_LONG).show();

                    }


                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError volleyError) {

                    // Hiding the progress dialog after all task complete.
                    progressDialog.dismiss();

                    // Showing error message if something goes wrong.
                    Log.i("log error", volleyError.toString());
                    Toast.makeText(Main2Activity.this, volleyError.toString(), Toast.LENGTH_LONG).show();
                }
            }) {
        //METHOD1
        @Override
        public Map<String, String> getParams() throws AuthFailureError {

            // Creating Map String Params.
            Map<String, String> params = new HashMap<String, String>();

            //code found on stackexhange
            params.put("Content-Type", "application/json");

            // Adding All values to headers/Params.
            // The firs argument should be same as your MySQL database table columns.
            params.put("email", EmailHolder);
            params.put("password", PasswordHolder);

            return params;

        }
                    //METHOD2
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> headers  = new HashMap<String, String>();
            headers.put("Content-Type", "application/json");
            String credentials = EmailHolder+":"+PasswordHolder;
            String auth = "Basic "+ Base64.encodeToString(credentials.getBytes(),
                    Base64.NO_WRAP);
            headers .put("Authorization", auth);

            return  headers ;
        }
    };
    // Creating RequestQueue.
    RequestQueue requestQueue = Volley.newRequestQueue(Main2Activity.this);

    //timeout policy
    stringRequest.setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    requestQueue.add(stringRequest);

    // Adding the StringRequest object into requestQueue.
    //requestQueue.add(stringRequest);

}


public void CheckEditTextIsEmptyOrNot() {

    // Getting values from EditText.
    EmailHolder = Email.getText().toString().trim();
    PasswordHolder = Password.getText().toString().trim();

    // Checking whether EditText value is empty or not.
    if (TextUtils.isEmpty(EmailHolder) || TextUtils.isEmpty(PasswordHolder)) {

        // If any of EditText is empty then set variable value as False.
        CheckEditText = false;

    } else {

        // If any of EditText is filled then set variable value as True.
        CheckEditText = true;
    }
}

}

мой пользовательский контроллер, отлично работает

    class UsersController < ApplicationController


      # Use Knock to make sure the current_user is authenticated before completing request.
  before_action :authenticate_user,  only: [:index, :current, :update]
  before_action :authorize_as_admin, only: [:destroy]
  before_action :authorize,          only: [:update]

  # Should work if the current_user is authenticated.
  def index
    render json: {status: 200, msg: 'Logged-in'}
  end

  # Method to create a new user using the safe params we setup.
def create
  user = User.new(user_params)
  if user.save
    render json: {status: 200, msg: 'User was created.'}
  end
end

# Method to update a specific user. User will need to be authorized.
def update
  user = User.find(params[:id])
  if user.update(user_params)
    render json: { status: 200, msg: 'User details have been updated.' }
  end
end

# Method to delete a user, this method is only for admin accounts.
def destroy
  user = User.find(params[:id])
  if user.destroy
    render json: { status: 200, msg: 'User has been deleted.' }
  end
end

  # Call this method to check if the user is logged-in.
  # If the user is logged-in we will return the user's information.
  def current
    current_user.update!(last_login: Time.now)
    render json: current_user
  end

  private

  # Setting up strict parameters for when we add account creation.
  def user_params
    params.require(:user).permit(:username, :email, :password, :password_confirmation)
  end

  # Adding a method to check if current_user can update itself. 
  # This uses our UserModel method.
  def authorize
    return_unauthorized unless current_user && current_user.can_modify_user?(params[:id])
  end

end
...