如何从应用程序控制器内部渲染带错误的json?

时间:2018-08-01 12:34:59

标签: ruby-on-rails

我正在使用Rails API。在我的 application_controller.rb ,我有一些方法可以通过查看json网络令牌的标头并对其进行解码来处理身份验证。如果令牌丢失或不正确,我想通过呈现未经身份验证的错误消息来响应请求。我尝试删除响应以处理每个错误,如下所示:

render json: { 'error': 'Some error message' }, status: 403

但它似乎永远不会流行。相反,我得到的错误看起来像这样:

{
    "status": 500,
    "error": "Internal Server Error",
    "exception": "#<JWT::DecodeError: Invalid segment encoding>",
    "traces": {
        "Application Trace": [
            {
                "id": 4,
                "trace": "app/controllers/application_controller.rb:13:in `decode_token'"
            },
            {
                "id": 5,
                "trace": "app/controllers/application_controller.rb:18:in `authenticate_current_user_from_token'"
            }
        ],
        "Framework Trace": [
            {
                "id": 0,
                "trace": "jwt (2.1.0) lib/jwt/decode.rb:46:in `rescue in decode_header_and_payload'"
            },
            {
                "id": 1,
                "trace": "jwt (2.1.0) lib/jwt/decode.rb:41:in `decode_header_and_payload'"
            },
            {
                "id": 2,
                "trace": "jwt (2.1.0) lib/jwt/decode.rb:26:in `decode_segments'"
            },
            {
                "id": 3,
                "trace": "jwt (2.1.0) lib/jwt.rb:31:in `decode'"
            },
            {
                "id": 6,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:426:in `block in make_lambda'"
            },
            {
                "id": 7,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:198:in `block (2 levels) in halting'"
            },
            {
                "id": 8,
                "trace": "actionpack (5.2.0) lib/abstract_controller/callbacks.rb:34:in `block (2 levels) in <module:Callbacks>'"
            },
            {
                "id": 9,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:199:in `block in halting'"
            },
            {
                "id": 10,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:513:in `block in invoke_before'"
            },
            {
                "id": 11,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:513:in `each'"
            },
            {
                "id": 12,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:513:in `invoke_before'"
            },
            {
                "id": 13,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:131:in `run_callbacks'"
            },
            {
                "id": 14,
                "trace": "actionpack (5.2.0) lib/abstract_controller/callbacks.rb:41:in `process_action'"
            },
            {
                "id": 15,
                "trace": "actionpack (5.2.0) lib/action_controller/metal/rescue.rb:22:in `process_action'"
            },
            {
                "id": 16,
                "trace": "actionpack (5.2.0) lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'"
            },
            {
                "id": 17,
                "trace": "activesupport (5.2.0) lib/active_support/notifications.rb:168:in `block in instrument'"
            },
            {
                "id": 18,
                "trace": "activesupport (5.2.0) lib/active_support/notifications/instrumenter.rb:23:in `instrument'"
            },
            {
                "id": 19,
                "trace": "activesupport (5.2.0) lib/active_support/notifications.rb:168:in `instrument'"
            },
            {
                "id": 20,
                "trace": "actionpack (5.2.0) lib/action_controller/metal/instrumentation.rb:32:in `process_action'"
            },
            {
                "id": 21,
                "trace": "actionpack (5.2.0) lib/action_controller/metal/params_wrapper.rb:256:in `process_action'"
            },
            {
                "id": 22,
                "trace": "activerecord (5.2.0) lib/active_record/railties/controller_runtime.rb:24:in `process_action'"
            },
            {
                "id": 23,
                "trace": "actionpack (5.2.0) lib/abstract_controller/base.rb:134:in `process'"
            },
            {
                "id": 24,
                "trace": "actionpack (5.2.0) lib/action_controller/metal.rb:191:in `dispatch'"
            },
            {
                "id": 25,
                "trace": "actionpack (5.2.0) lib/action_controller/metal.rb:252:in `dispatch'"
            },
            {
                "id": 26,
                "trace": "actionpack (5.2.0) lib/action_dispatch/routing/route_set.rb:52:in `dispatch'"
            },
            {
                "id": 27,
                "trace": "actionpack (5.2.0) lib/action_dispatch/routing/route_set.rb:34:in `serve'"
            },
            {
                "id": 28,
                "trace": "actionpack (5.2.0) lib/action_dispatch/journey/router.rb:52:in `block in serve'"
            },
            {
                "id": 29,
                "trace": "actionpack (5.2.0) lib/action_dispatch/journey/router.rb:35:in `each'"
            },
            {
                "id": 30,
                "trace": "actionpack (5.2.0) lib/action_dispatch/journey/router.rb:35:in `serve'"
            },
            {
                "id": 31,
                "trace": "actionpack (5.2.0) lib/action_dispatch/routing/route_set.rb:840:in `call'"
            },
            {
                "id": 32,
                "trace": "rack (2.0.5) lib/rack/etag.rb:25:in `call'"
            },
            {
                "id": 33,
                "trace": "rack (2.0.5) lib/rack/conditional_get.rb:25:in `call'"
            },
            {
                "id": 34,
                "trace": "rack (2.0.5) lib/rack/head.rb:12:in `call'"
            },
            {
                "id": 35,
                "trace": "activerecord (5.2.0) lib/active_record/migration.rb:559:in `call'"
            },
            {
                "id": 36,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'"
            },
            {
                "id": 37,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:98:in `run_callbacks'"
            },
            {
                "id": 38,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/callbacks.rb:26:in `call'"
            },
            {
                "id": 39,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/executor.rb:14:in `call'"
            },
            {
                "id": 40,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:61:in `call'"
            },
            {
                "id": 41,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'"
            },
            {
                "id": 42,
                "trace": "railties (5.2.0) lib/rails/rack/logger.rb:38:in `call_app'"
            },
            {
                "id": 43,
                "trace": "railties (5.2.0) lib/rails/rack/logger.rb:26:in `block in call'"
            },
            {
                "id": 44,
                "trace": "activesupport (5.2.0) lib/active_support/tagged_logging.rb:71:in `block in tagged'"
            },
            {
                "id": 45,
                "trace": "activesupport (5.2.0) lib/active_support/tagged_logging.rb:28:in `tagged'"
            },
            {
                "id": 46,
                "trace": "activesupport (5.2.0) lib/active_support/tagged_logging.rb:71:in `tagged'"
            },
            {
                "id": 47,
                "trace": "railties (5.2.0) lib/rails/rack/logger.rb:26:in `call'"
            },
            {
                "id": 48,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'"
            },
            {
                "id": 49,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/request_id.rb:27:in `call'"
            },
            {
                "id": 50,
                "trace": "rack (2.0.5) lib/rack/runtime.rb:22:in `call'"
            },
            {
                "id": 51,
                "trace": "activesupport (5.2.0) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'"
            },
            {
                "id": 52,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/executor.rb:14:in `call'"
            },
            {
                "id": 53,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/static.rb:127:in `call'"
            },
            {
                "id": 54,
                "trace": "rack (2.0.5) lib/rack/sendfile.rb:111:in `call'"
            },
            {
                "id": 55,
                "trace": "rack-cors (1.0.2) lib/rack/cors.rb:97:in `call'"
            },
            {
                "id": 56,
                "trace": "railties (5.2.0) lib/rails/engine.rb:524:in `call'"
            },
            {
                "id": 57,
                "trace": "puma (3.12.0) lib/puma/configuration.rb:225:in `call'"
            },
            {
                "id": 58,
                "trace": "puma (3.12.0) lib/puma/server.rb:658:in `handle_request'"
            },
            {
                "id": 59,
                "trace": "puma (3.12.0) lib/puma/server.rb:472:in `process_client'"
            },
            {
                "id": 60,
                "trace": "puma (3.12.0) lib/puma/server.rb:332:in `block in run'"
            },
            {
                "id": 61,
                "trace": "puma (3.12.0) lib/puma/thread_pool.rb:133:in `block in spawn_thread'"
            }
        ],
        "Full Trace": [
            {
                "id": 0,
                "trace": "jwt (2.1.0) lib/jwt/decode.rb:46:in `rescue in decode_header_and_payload'"
            },
            {
                "id": 1,
                "trace": "jwt (2.1.0) lib/jwt/decode.rb:41:in `decode_header_and_payload'"
            },
            {
                "id": 2,
                "trace": "jwt (2.1.0) lib/jwt/decode.rb:26:in `decode_segments'"
            },
            {
                "id": 3,
                "trace": "jwt (2.1.0) lib/jwt.rb:31:in `decode'"
            },
            {
                "id": 4,
                "trace": "app/controllers/application_controller.rb:13:in `decode_token'"
            },
            {
                "id": 5,
                "trace": "app/controllers/application_controller.rb:18:in `authenticate_current_user_from_token'"
            },
            {
                "id": 6,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:426:in `block in make_lambda'"
            },
            {
                "id": 7,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:198:in `block (2 levels) in halting'"
            },
            {
                "id": 8,
                "trace": "actionpack (5.2.0) lib/abstract_controller/callbacks.rb:34:in `block (2 levels) in <module:Callbacks>'"
            },
            {
                "id": 9,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:199:in `block in halting'"
            },
            {
                "id": 10,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:513:in `block in invoke_before'"
            },
            {
                "id": 11,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:513:in `each'"
            },
            {
                "id": 12,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:513:in `invoke_before'"
            },
            {
                "id": 13,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:131:in `run_callbacks'"
            },
            {
                "id": 14,
                "trace": "actionpack (5.2.0) lib/abstract_controller/callbacks.rb:41:in `process_action'"
            },
            {
                "id": 15,
                "trace": "actionpack (5.2.0) lib/action_controller/metal/rescue.rb:22:in `process_action'"
            },
            {
                "id": 16,
                "trace": "actionpack (5.2.0) lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'"
            },
            {
                "id": 17,
                "trace": "activesupport (5.2.0) lib/active_support/notifications.rb:168:in `block in instrument'"
            },
            {
                "id": 18,
                "trace": "activesupport (5.2.0) lib/active_support/notifications/instrumenter.rb:23:in `instrument'"
            },
            {
                "id": 19,
                "trace": "activesupport (5.2.0) lib/active_support/notifications.rb:168:in `instrument'"
            },
            {
                "id": 20,
                "trace": "actionpack (5.2.0) lib/action_controller/metal/instrumentation.rb:32:in `process_action'"
            },
            {
                "id": 21,
                "trace": "actionpack (5.2.0) lib/action_controller/metal/params_wrapper.rb:256:in `process_action'"
            },
            {
                "id": 22,
                "trace": "activerecord (5.2.0) lib/active_record/railties/controller_runtime.rb:24:in `process_action'"
            },
            {
                "id": 23,
                "trace": "actionpack (5.2.0) lib/abstract_controller/base.rb:134:in `process'"
            },
            {
                "id": 24,
                "trace": "actionpack (5.2.0) lib/action_controller/metal.rb:191:in `dispatch'"
            },
            {
                "id": 25,
                "trace": "actionpack (5.2.0) lib/action_controller/metal.rb:252:in `dispatch'"
            },
            {
                "id": 26,
                "trace": "actionpack (5.2.0) lib/action_dispatch/routing/route_set.rb:52:in `dispatch'"
            },
            {
                "id": 27,
                "trace": "actionpack (5.2.0) lib/action_dispatch/routing/route_set.rb:34:in `serve'"
            },
            {
                "id": 28,
                "trace": "actionpack (5.2.0) lib/action_dispatch/journey/router.rb:52:in `block in serve'"
            },
            {
                "id": 29,
                "trace": "actionpack (5.2.0) lib/action_dispatch/journey/router.rb:35:in `each'"
            },
            {
                "id": 30,
                "trace": "actionpack (5.2.0) lib/action_dispatch/journey/router.rb:35:in `serve'"
            },
            {
                "id": 31,
                "trace": "actionpack (5.2.0) lib/action_dispatch/routing/route_set.rb:840:in `call'"
            },
            {
                "id": 32,
                "trace": "rack (2.0.5) lib/rack/etag.rb:25:in `call'"
            },
            {
                "id": 33,
                "trace": "rack (2.0.5) lib/rack/conditional_get.rb:25:in `call'"
            },
            {
                "id": 34,
                "trace": "rack (2.0.5) lib/rack/head.rb:12:in `call'"
            },
            {
                "id": 35,
                "trace": "activerecord (5.2.0) lib/active_record/migration.rb:559:in `call'"
            },
            {
                "id": 36,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'"
            },
            {
                "id": 37,
                "trace": "activesupport (5.2.0) lib/active_support/callbacks.rb:98:in `run_callbacks'"
            },
            {
                "id": 38,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/callbacks.rb:26:in `call'"
            },
            {
                "id": 39,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/executor.rb:14:in `call'"
            },
            {
                "id": 40,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:61:in `call'"
            },
            {
                "id": 41,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'"
            },
            {
                "id": 42,
                "trace": "railties (5.2.0) lib/rails/rack/logger.rb:38:in `call_app'"
            },
            {
                "id": 43,
                "trace": "railties (5.2.0) lib/rails/rack/logger.rb:26:in `block in call'"
            },
            {
                "id": 44,
                "trace": "activesupport (5.2.0) lib/active_support/tagged_logging.rb:71:in `block in tagged'"
            },
            {
                "id": 45,
                "trace": "activesupport (5.2.0) lib/active_support/tagged_logging.rb:28:in `tagged'"
            },
            {
                "id": 46,
                "trace": "activesupport (5.2.0) lib/active_support/tagged_logging.rb:71:in `tagged'"
            },
            {
                "id": 47,
                "trace": "railties (5.2.0) lib/rails/rack/logger.rb:26:in `call'"
            },
            {
                "id": 48,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'"
            },
            {
                "id": 49,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/request_id.rb:27:in `call'"
            },
            {
                "id": 50,
                "trace": "rack (2.0.5) lib/rack/runtime.rb:22:in `call'"
            },
            {
                "id": 51,
                "trace": "activesupport (5.2.0) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'"
            },
            {
                "id": 52,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/executor.rb:14:in `call'"
            },
            {
                "id": 53,
                "trace": "actionpack (5.2.0) lib/action_dispatch/middleware/static.rb:127:in `call'"
            },
            {
                "id": 54,
                "trace": "rack (2.0.5) lib/rack/sendfile.rb:111:in `call'"
            },
            {
                "id": 55,
                "trace": "rack-cors (1.0.2) lib/rack/cors.rb:97:in `call'"
            },
            {
                "id": 56,
                "trace": "railties (5.2.0) lib/rails/engine.rb:524:in `call'"
            },
            {
                "id": 57,
                "trace": "puma (3.12.0) lib/puma/configuration.rb:225:in `call'"
            },
            {
                "id": 58,
                "trace": "puma (3.12.0) lib/puma/server.rb:658:in `handle_request'"
            },
            {
                "id": 59,
                "trace": "puma (3.12.0) lib/puma/server.rb:472:in `process_client'"
            },
            {
                "id": 60,
                "trace": "puma (3.12.0) lib/puma/server.rb:332:in `block in run'"
            },
            {
                "id": 61,
                "trace": "puma (3.12.0) lib/puma/thread_pool.rb:133:in `block in spawn_thread'"
            }
        ]
    }
}

这是我的应用程序控制器:

application_controller.rb

class ApplicationController < ActionController::API
  def encode_token(payload)
    JWT.encode(payload, ENV['JWT_SECRET'])
  end

  def retrieve_token_from_header
    request.headers['Authorization']
    # TODO: return error if doesn't exist
  end

  def decode_token
    token = retrieve_token_from_header.split(' ')[1]
    JWT.decode(token, ENV['JWT_SECRET'], true, algorithm: 'HS256')
    # TODO: return error if invalid
  end

  def authenticate_current_user_from_token
    user_id = decode_token[0]['user_id']
    @user = User.find(user_id)
    # TODO: return error if user not found
  end
end

任何帮助都将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:1)

您需要rescue_from的{​​{1}}顶部有处理程序,下面是一个示例:

ApplicationController