当前位置: 首页 > 知识库问答 >
问题:

Volley忽略Cookie标头请求

汝吕恭
2023-03-14

很好的一天!

我的应用程序使用简单的http客户端-服务器通信,通过客户端的凌空库建立。首先,我启动一个授权请求:

public class AuthenticationRequest extends StringRequest {

    private static final String TAG = AuthenticationRequest.class.getSimpleName();

    private String login;
    private String password;

    public AuthenticationRequest(int method,
                                 String url,
                                 Response.Listener<String> listener,
                                 Response.ErrorListener errorListener) {
        super(method, url, listener, errorListener);
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    protected Map<String, String> getParams() {
        HashMap<String, String> parameters = new HashMap<>();
        parameters.put("login", login);
        parameters.put("password", password);
        return parameters;
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        for (Map.Entry<String, String> entry : response.headers.entrySet()) {
            Log.d(TAG, entry.getKey() + " -- " + entry.getValue());
        }

        String sessionId = response.headers.get("Set-Cookie");
        return Response.success(sessionId, HttpHeaderParser.parseCacheHeaders(response));
    }
}

之后,我请求列出与当前用户相关的设备列表。此时,我收到了来自响应标题的cookei。auth请求的完整标头响应输出:

  • 缓存控制——没有存储,没有缓存,必须重新验证,后检查=0,预检查=0

在身份验证请求的onResponce回调中,我将Set Cookie值作为sessionId,并启动DeviceListRequest:

public class DeviceListRequest extends StringRequest {

    private static final String TAG = DeviceListRequest.class.getSimpleName();

    private String phpSessId;

    public DeviceListRequest(int method,
                             String url,
                             Response.Listener<String> listener,
                             Response.ErrorListener errorListener) {
        super(method, url, listener, errorListener);
    }

    public void setPhpSessId(String phpSessId) {
        this.phpSessId = phpSessId;
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        HashMap<String, String> headers = new HashMap<>();
        Log.d(TAG, phpSessId);
        headers.put("Cookie", phpSessId);
        return headers;
    }
}

在这里,我将sessionId放在设备列表请求的头中,但在响应中我看到:{“status”:false,“error”:“No authorization”}

在Chrome浏览器桌面PC接收设备的预期列表-问题是在Android上。

请问,我的代码有什么问题?也许我在设置标题时出错了???

发送请求程序代码:

public void authenticationRequest(String login, String password) {
        final AuthenticationRequest request = new AuthenticationRequest(Request.Method.GET,
                AUTHENTICATION_URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        Log.d(TAG, "Response: " + response);
                        phpSessId = response;
                        deviceListRequest(phpSessId);
                    }
                },
                this);

        request.setLogin(login);
        request.setPassword(password);

        requestQueue.add(request);
    }

    public void deviceListRequest(String phpSessId) {
        DeviceListRequest request = new DeviceListRequest(Request.Method.GET,
                DEVICE_LIST_URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        Log.d(TAG, "Response: " + response);
                    }
                },
                this);

        request.setPhpSessId(phpSessId);

        requestQueue.add(request);
    }

共有2个答案

曾涵育
2023-03-14

我也遇到了Volley标头操作的问题。检查Volley中包含的HurlStack的源代码。

凌空中的标题放在地图中,有时(我仍然不知道为什么),凌空会一个接一个地收集同一个键(在你的情况下是Set Cookie)的标题(首先是这个PHPSESSION,然后它会得到Set Cookie的这个路径部分)。因为这是一个地图,第一个会被覆盖,你不会得到你想要的。

我的建议是修改HurlStack的源代码,以便在列表中获取这些头文件,或者使用不同的键(Set-Cookie1,Set-Cookie2,…)。

再看看改装,它处理得真不错。唯一的问题是,通过改装,您不可能取消请求。

希望这有帮助。

东郭鸿福
2023-03-14

如果您不需要与Android兼容

CookieHandler.setDefault(new CookieManager());

希望这有帮助。

如果您需要更大的向后兼容性,还需要对HttpClient进行Cookie管理

编辑:在后一种情况下,按照此答案传递自定义HttpClientStack:https://stackoverflow.com/a/21271347

 类似资料:
  • 我正在开发一个客户端基于AngularJS的应用程序,服务器端基于我的API(Tomcat+Jersey for WS)的Java。 我的API的某些路径受到限制,如果用户没有会话,则返回的响应状态为401。在客户端,拦截401个http状态以将用户重定向到登录页面。 用户通过身份验证后,我将在服务器端创建一个会话 null 问题是cookie从不放在客户端。当我检查localhost域的cook

  • 我的后端是sprin引导应用程序,前端是vue js 但是cookie值没有设置在请求头部和所有其他api失败与身份验证问题,因为cookie值(会话ID)不存在于头部 样本响应头部与set-cookie身份验证 下面是我在vue.config.js中的代理配置 这是我的axios实例创建与"with凭据:真" 下面是我在服务器端的web安全配置 注意:这在邮递员中工作,因为邮递员会自动将cook

  • 我有一个正在构建的用于访问Web服务的客户端。我正在使用一些JAXB生成的类(Netbean 6.9)来散集我的xml数据。 当试图从这个Web服务解组InputStream响应时,我会遇到意外的元素错误,如果我将响应保存到文件中,我也会遇到同样的意外元素错误。 使用保存到文件中的数据,我可以进入并删除SOAP标签(信封、正文、标头),然后毫无问题地运行解组。 我还没有真正找到一种方法让未婚夫忽略

  • 我正在使用kotlin开发一个android应用程序,在这条道路上,我想使用请求来响应restall服务器...现在看看我从服务器请求它的代码,它是真的,但我不知道如何将头的参数添加到我的请求

  • 问题内容: 我正在尝试访问网站,但无法将收集到的“ Cookie”添加到传出的POST请求标头中。我已经能够验证它们是否存在于CookieManager中。 HtmlUnit的任何替代方法也将不胜感激。 问题答案: 我发现可以使用WebClient中的setadditionalHeader()添加标题。

  • 问题内容: 我正在尝试通过AJAX从本地主机上的Google云存储中获取文件。我已经完成以下工作: 通过gsutil为我的存储桶设置CORS: 其中cors.json文件为: 我已经用 然后,对于每个文件,我都会通过上传文件时通过node.js客户端库将其公开: 通过控制台和gsutil: 然后在我的ajax请求中,我还发送标头: 而且仍然出现cors错误: 对预检请求的响应未通过访问控制检查:在