android 将Cookie添加到改型2请求

jogvjijk  于 2022-12-21  发布在  Android
关注(0)|答案(6)|浏览(161)

我需要添加与改型2.0的cookie。如果我理解正确,cookie-与标题相同。必须添加此cookie:

private HashMap<String, String> cookies = new HashMap();
cookies.put("sessionid", "sessionId");
cookies.put("token", "token");

这一个使用Jsoup库:

String json = Jsoup.connect(apiURL + "/link")
                    .cookies(cookies)
                    .ignoreHttpErrors(true)
                    .ignoreContentType(true)
                    .execute()
                    .body();

下面是我代码,带有翻新请求:

@GET("link")
Call<CbGet> getData(@Header("sessionid") String sessionId, @Header("token") String token);

但它是不工作...我得到403错误代码,所以没有cookie在请求...
你知道吗?

j9per5c4

j9per5c41#

首先:Cookie与标头不同。Cookie是一个名为Cookie的特殊HTTP标头,后跟键和值对的列表(以""分隔; ")。类似于:

Cookie: sessionid=sessionid; token=token

由于you cannot set multiple Cookie headers in the same request,您不能为单独的值使用两个*@Header * 注解(在您的示例中为 * sessionid * 和 * token *)。

@GET("link")
Call<CbGet> getData(@Header("Cookie") String sessionIdAndToken);

您更改了方法,将sessionId和token放在一个字符串中发送。因此,在这种情况下,您应该事先手动生成cookie字符串。在这种情况下,sessionIdAndToken String对象应该等于"sessionid =* here_goes_sessionid ;令牌= 此处为令牌 *"

    • 正确的解决方案是通过添加OkHttp**(即Retrofit用于进行底层http调用的库)request interceptor来设置cookie。您可以查看解决方案或添加自定义头here
s5a0g9ez

s5a0g9ez2#

为什么不使用cookieJar选项呢?

new Retrofit.Builder()
    .baseUrl(BASE_URL)
    .client(
        new OkHttpClient().newBuilder()
            .cookieJar(new SessionCookieJar()).build())
    .build();

private static class SessionCookieJar implements CookieJar {

    private List<Cookie> cookies;

    @Override
    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
        if (url.encodedPath().endsWith("login")) {
            this.cookies = new ArrayList<>(cookies);
        }
    }

    @Override
    public List<Cookie> loadForRequest(HttpUrl url) {
        if (!url.encodedPath().endsWith("login") && cookies != null) {
            return cookies;
        }
        return Collections.emptyList();
    }
}
1wnzp6jl

1wnzp6jl3#

API Web服务示例添加标题

@FormUrlEncoded
@POST("getDriverRoutes")
Call<Guzergah> getGuzergah(@Header("Cookie") String userCookie, @Field("driver_id") int driver_id);

当您登录到系统保存cookie到您的本地上响应像

public void onResponse(Response<Login> response, Retrofit retrofit) {
            hidepDialog();
            String cookie = response.headers().get("Set-Cookie");
            editor.putString("user_cookie", cookie.split(";")[0]);
            editor.commit();

在每一个需要授权的服务中,发送您的cookie,从shareperference获取并与您的Web服务一起发送

String userCookie = shp.getString("user_cookie", ""); // here is cookies before send
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://server.aracadabra.com:8080/").
                    addConverterFactory(GsonConverterFactory.create())
            .build();

    final APIService service = retrofit.create(APIService.class);

    final Call<SenMsgStatus> loginMCall = service.sendMessage(userCookie, type, route_id, user_id, passenger_id, passenger_status, text);
m3eecexj

m3eecexj4#

要将cookie标头添加到okhttp请求标头,请在拦截器中添加以下内容:
第一个月
参考:@ Alexandria Mironov提到的https://github.com/square/okhttp/wiki/Interceptors
完整示例代码如下:希望对你有帮助

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;

public class LoggingInterceptor implements Interceptor {

    private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request request = chain.request();

        long t1 = System.nanoTime();
        request = processRequest(request);
        logger.info("Sending request with url:{} and connection status:{} and request headers:{}",
                request.url(), chain.connection(), request.headers());

        Response response = chain.proceed(request);
        long t2 = System.nanoTime();
        logger.info("Received response for url:{} and time taken:{} and response headers as:{}",
                response.request().url(), (t2 - t1) / 1e6d, response.headers());

        response = processResponse(response);
        return response;
    }
    //Add cookies for all subsequent requests
    private Request processRequest(Request request) {
        if(!request.url().toString().contains("/v1/authorize")) {
            final EmployeeSession session = getSession();
            StringBuilder etokenAndUId = new StringBuilder("etoken=");
            etokenAndUId.append(session.getEtoken()).append(";").append("uId=").append(session.getUId());
            logger.info("inside processRequest for all subsequent requests, sending cookies as etokenAndUId values:{}", etokenAndUId.toString());
            request= request.newBuilder().addHeader("Cookie", etokenAndUId.toString()).build();
        }
        return request;
    }

    //Extract cookies from login url
    private Response processResponse(Response response) {
        if(response.request().url().toString().contains("/v1/authorize")) {
            final List<String> cookieHeaders = response.headers("Set-Cookie");
            String etoken = "", uId = "";
            for (String cookieHeader : cookieHeaders) {
                if(cookieHeader.contains("etoken=")) {
                    etoken = cookieHeader.substring(7, cookieHeader.indexOf(';'));
                }
                else if(cookieHeader.contains("uId=")) {
                    uId = cookieHeader.substring(4, cookieHeader.indexOf(';'));
                }
            }
            logger.info("inside processResponse found cookies from login url response: etoken:{} and uid:{}", etoken, uId);
            setSession(etoken, uId, "c1");
            logger.info("current employee session:{}", getSession());
        }
        return response;
    }
 }
5gfr0r5j

5gfr0r5j5#

    • 您可以使用拦截器通过改型添加Cookie,这是我们在API请求中动态管理Cookie的最佳解决方案。**

我试过使用JavaNetCookieJar(cookieManager),但在我的情况下不起作用,所以我使用了拦截器,它也可以使用依赖注入n(Dagger以及Koin)。

    • 步骤1:创建 * ReceivedCookiesInterceptor类以接收Cookie。
      Java Code: ReceivedCookiesInterceptor.java
public class ReceivedCookiesInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
    Response originalResponse = chain.proceed(chain.request());

    if (!originalResponse.headers("Set-Cookie").isEmpty()) {
        HashSet<String> cookies = new HashSet<>();

        for (String header : originalResponse.headers("Set-Cookie")) {
          cookies.add(header);
        }

        Preferences.getDefaultPreferences().edit()
                .putStringSet(Preferences.PREF_COOKIES, cookies)
                .apply();
    }

    return originalResponse;
} 
}
    • Kotlin代码:接收Cookie拦截器. Kt**
class ReceivedCookiesInterceptor : Interceptor {
        @Throws(IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            val originalResponse: Response = chain.proceed(chain.request())
            if (originalResponse.headers("Set-Cookie").isNotEmpty()) {
                val cookies: HashSet<String> = HashSet()
                for (header in originalResponse.headers("Set-Cookie")) {
                    cookies.add(header)
                }
                preferenceProvider.putStringSet("PREF_COOKIES", cookies)  
                // Prefrence Provider In My SharedPrefrence Object
            }
            return originalResponse
        }
    }
    • 步骤2:创建AddCookiesInterceptor类以存储Cookie。**
      Java Code: AddCookiesInterceptorclass.java
public class AddCookiesInterceptor implements Interceptor {

@Override
public Response intercept(Chain chain) throws IOException {
    Request.Builder builder = chain.request().newBuilder();
    HashSet<String> preferences = (HashSet) Preferences.getDefaultPreferences().getStringSet(Preferences.PREF_COOKIES, new HashSet<>());
    for (String cookie : preferences) {
        builder.addHeader("Cookie", cookie);
        Log.v("OkHttp", "Adding Header: " + cookie); // This is done so I know which headers are being added; this interceptor is used after the normal logging of OkHttp
    }

    return chain.proceed(builder.build());
}
}
    • Kotlin代码:添加Cookie侦听器类. kt**
class AddCookiesInterceptor : Interceptor {
        @Throws(IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            val builder: Request.Builder = chain.request().newBuilder()
            val prefCookies: HashSet<String> =
                preferenceProvider.getStringSet("PREF_COOKIES", HashSet())
            for (cookie in prefCookies) {
                builder.addHeader("Cookie", cookie)
            }
            return chain.proceed(builder.build())
        }
    }
    • 步骤3:将这些拦截器添加到okHttpClientObject中**
    • Java代码:用于在改造请求中添加拦截器**
OkHttpClient okHttpClient = new OkHttpClient();
     okHttpClient.interceptors().add(new AddCookiesInterceptor());
    okHttpClient.interceptors().add(new ReceivedCookiesInterceptor());
    • Kotlin代码:用于在改装请求中添加拦截器**
val okHttpClient = OkHttpClient().newBuilder()
        .connectionSpecs(specs)
        .addInterceptor(requestInterceptor)
        .addInterceptor(AddCookiesInterceptor())
        .addInterceptor(ReceivedCookiesInterceptor())
5q4ezhmt

5q4ezhmt6#

下面是一些Kotlin代码,用于调用传递给Retrofit2的OkHttpClient(v3)中的CookieManager

val client = OkHttpClient.Builder()
        .cookieJar(object : CookieJar {
            private val cookieStore = HashMap<HttpUrl?, List<Cookie>>()
            private val cookieManager = CookieManager.getInstance()

            override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
                val host = url.host()
                cookieStore[HttpUrl.parse(host)] = cookies
                cookieManager.removeAllCookie()
                val cookies1 = cookieStore[HttpUrl.parse(host)]
                if (cookies1 != null) {
                    for (cookie in cookies1) {
                        val cookieString =
                            cookie.name() + "=" + cookie.value() + "; path=" + cookie.path()
                        cookieManager.setCookie(cookie.domain(), cookieString)
                    }
                }
            }

            override fun loadForRequest(url: HttpUrl): List<Cookie> {
                val host = url.host()
                val cookies = cookieStore[HttpUrl.parse(host)]
                return cookies ?: ArrayList()
            }
        })
        .build()

    CookieManager.getInstance().setAcceptCookie(true)

    val retrofit2 = Retrofit.Builder().baseUrl(baseUrl)
            // converter factory for converting JSON to object
            .addConverterFactory(GsonConverterFactory.create(gson))
            .client(client)
            .build()

在您的版本中。gradle dependencies

dependencies {
    ...
    implementation 'androidx.webkit:webkit:1.5.0'

相关问题