更改状态代码 Rails

Change status code Rails

我的处境真的很糟糕。

我在 Android 应用程序上使用 Volley,在 Rails JSON API.

上使用 Ruby

问题是 Volley 存在一个错误,导致它无法正确识别状态为 401 的任何内容。基本上,只要有 401 状态,NetworkResponse 就是 null 并且 VolleyError 是 NoConnectionError 类型。

我搜索了很多,唯一的办法是 return 403 而不是 Volley 可以正确识别的 401。

如果在 rails 中是 401,我如何更改对 403 的所有响应的状态代码?我无法控制所有操作,例如 return 403 在设计预制操作时。

有没有办法在 rails 中完成回复或其他内容?

由于 devise 使用 warden,您可以创建一个自定义故障应用程序并设置您想要的 http 状态。

在lib/custom_failure.rb

class CustomFailure < Devise::FailureApp
  def respond
    self.status = 403 
    self.content_type = 'json'
    self.response_body = { error: "Invalid Email or password."}.to_json
  end 
end

在config/initializers/devise.rb

config.warden do |manager|
  manager.failure_app = CustomFailure
end 

在config/application.rb

config.autoload_paths << Rails.root.join('lib')

401 状态代码可能带有空白响应数据,如果您检查此 volley code 行 63-75

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

如果 jsonString 为空,它仍会尝试从中创建一个 JSONObject new JSONObject(jsonString),这会抛出 JSONException

您可以下载 volley 源代码,将其作为模块导入到您的 android studio 项目中,添加它的依赖项并进行以下更正:

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
//          Fix for an error on blank success response
//          return Response.success(new JSONObject(jsonString),
//                    HttpHeaderParser.parseCacheHeaders(response));
            if (!jsonString.trim().contentEquals("")) {
                return Response.success(new JSONObject(jsonString),
                        HttpHeaderParser.parseCacheHeaders(response));
            }
            else {
                return Response.success(new JSONObject(),
                        HttpHeaderParser.parseCacheHeaders(response));
            }
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }
}

要将 Volley 添加到您的项目 - 克隆 Volley 存储库并将其设置为库项目

  1. Git 通过在命令行中键入以下内容来克隆存储库:

    git clone https://android.googlesource.com/platform/frameworks/volley

  2. 按照 Create an Android Library.

  3. 中所述,将下载的源作为 Android 库模块导入到您的应用程序项目中

如果您不想在导入的库中进行修复,您也可以尝试 Prase 401 volley error message

我从 Ruby on Rails 后端找到了解决我的问题的方法,该方法适用于整个应用程序,这是必需的,因为很多控制器也会提供 401 而不仅仅是 [=14] =].

我通过执行以下操作使用了 Rack 中间件:

app/middleware/unauthorized_to_forbidden.rb

class   UnauthorizedToForbidden
    def initialize(app)
        @app = app 
    end

    def call(env)
        status, headers, response = @app.call(env)
        if(status == 401)
            status = 403
        end
        [status, headers, response]
    end
end

config/application.rb

class Application < Rails::Application
    config.middleware.use "UnauthorizedToForbidden"
end

现在 UnauthorizedToForbidden 位于 Rack 堆栈的底部,并在响应实际发送给用户之前的最后执行。如果它是 401403.

,它基本上会更改状态代码