如何在Retrofit中检索cookie?

时间:2014-03-15 15:47:21

标签: android cookies retrofit

我读到了关于请求拦截器以及什么不是但不知道如何真正使用它们来获取cookie ...我从nodejs发送这样的cookie ...

res.cookie('userid', user._id, { maxAge: 86400000, signed: true, path: '/' });

在我的Android客户端 - 到目前为止我已经为我的RestApiManager

设置了这个
public class RestApiManager {
  private static final String API_URL = "ip: port";

    private static final RestAdapter REST_ADAPTER = new RestAdapter.Builder()
            .setEndpoint(API_URL)
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .build();

    //Call interface
    public interface AsynchronousApi {
  //Login User
        @FormUrlEncoded
        @POST("/login")
        public void loginUser(
                @Field("loginName") String loginName,
                @Field("password") String password,
                Callback<UserResponse> callback);
//Profile Picture
        @Multipart
        @POST("/profilePicture")
        public void uploadProfilePicture(
                @Part("photo") TypedFile photo,
                @Part("userId") String userId,
                Callback<UserResponse> callback); //success thumbnail to picasso

    }
    //create adapter
    private static final AsynchronousApi ASYNCHRONOUS_API = REST_ADAPTER.create(AsynchronousApi.class);

    //call service to initiate
    public static AsynchronousApi getAsyncApi() {
        return ASYNCHRONOUS_API;
    }
}

单独的cookie类:

    public class ApiCookie implements RequestInterceptor{
    // cookie use
    private String sessionId;

    public ApiCookie() {

    }

    //COOKIE BELOW
    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }

    public void clearSessionId() {
        sessionId = null;
    }


    @Override
    public void intercept(RequestFacade requestFacade) {
        setSessionId();
    }
}

试图弄清楚如何获取cookie并能够将其与未来的请求一起发送,所以我不需要包含userId字段?

4 个答案:

答案 0 :(得分:10)

我的应用程序中有类似的情况。此解决方案适用于我使用Retrofit检索cookie。 的 MyCookieManager.java

import java.io.IOException;
import java.net.CookieManager;
import java.net.URI;
import java.util.List;
import java.util.Map;

class MyCookieManager extends CookieManager {

    @Override
    public void put(URI uri, Map<String, List<String>> stringListMap) throws IOException {
        super.put(uri, stringListMap);
        if (stringListMap != null && stringListMap.get("Set-Cookie") != null)
            for (String string : stringListMap.get("Set-Cookie")) {
                if (string.contains("userid")) {
                    //save your cookie here
                }
            }
    }
}

以下是如何使用RequestInterceptor为将来的请求设置cookie:

 MyCookieManager myCookieManager = new MyCookieManager();
            CookieHandler.setDefault(myCookieManager);
 private static final RestAdapter REST_ADAPTER = new RestAdapter.Builder()
            .setEndpoint(API_URL)
            .setLogLevel(RestAdapter.LogLevel.FULL)
                    .setRequestInterceptor(new RequestInterceptor() {
                        @Override
                        public void intercept(RequestFacade requestFacade) {
                            String userId = ;//get your saved userid here
                            if (userId != null)
                                requestFacade.addHeader("Cookie", userId);
                        }
                    })
            .build();

答案 1 :(得分:1)

使用lib的简单解决方案。 JavaNetCookieJar jncj = new JavaNetCookieJar(CookieHandler.getDefault()); OkHttpClient.Builder().cookieJar(jncj).build();

MyRequestOptions

答案 2 :(得分:0)

我在Kotlin中创建了拦截器以获取cookie(仅过滤http的cookie),并在每个请求中发送标头,直到用户注销(并使用clearCookie()方法)

class CookiesInterceptor: Interceptor {

    companion object {
        const val COOKIE_KEY = "Cookie"
        const val SET_COOKIE_KEY = "Set-Cookie"
    }

    fun clearCookie() {
        cookie = null
    }

    private var cookie: String? = null

    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val requestBuilder = request.newBuilder()
        cookie?.let { requestBuilder.addHeader(COOKIE_KEY, it) }

        val response = chain.proceed(requestBuilder.build())
        response.headers()
                .toMultimap()[SET_COOKIE_KEY]
                ?.filter { !it.contains("HttpOnly") }
                ?.getOrNull(0)
                ?.also {
                    cookie = it
                }

        return response
    }

}

答案 3 :(得分:0)

@Rafolos您的回答救了我,它完美而干净。您只需确保对以下所有请求使用相同的拦截器对象,否则,如果为每个调用实例化新的CookiesInterceptor,则cookie将为null。

我有一个具有以下属性的RetrofitProvider对象:

private val cookiesInterceptor: CookiesInterceptor by lazy {
    CookiesInterceptor()
}

然后我像这样使用它:

private fun provideOkHttpClient(): OkHttpClient {
    val httpClient = OkHttpClient.Builder()

    httpClient.addInterceptor(this.cookiesInterceptor)
    // add some other interceptors

    return httpClient.build()
}

,它就像一种魅力。 谢谢!