【问题标题】:How to retrieve cookies in Retrofit?如何在 Retrofit 中检索 cookie?
【发布时间】:2014-04-20 23:36:12
【问题描述】:

我阅读了有关请求拦截器的信息,但不知道如何真正使用它们来获取 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 字段?

【问题讨论】:

  • 您是否尝试过启用cookies?只需在某处致电CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
  • 如果我这样做,那么它会在我发出的每个请求上自动发送 cookie 吗?
  • 是的,至少如果您使用 okhttp 作为底层 http-transport 实现,它会。这就是我在应用程序中处理 cookie 的方式。
  • 在登录页面上我应该在哪里准确地调用它 - 就足够了吗?
  • 我从自定义 Application 类的 onCreate 方法调用它

标签: android cookies retrofit


【解决方案1】:

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

我有一个具有此属性的 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()
}

它就像一个魅力。 谢谢!

【讨论】:

    【解决方案2】:

    我在 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】:

      使用 lib 的简单解决方案。 compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'.

      JavaNetCookieJar jncj = new JavaNetCookieJar(CookieHandler.getDefault()); OkHttpClient.Builder().cookieJar(jncj).build();

      【讨论】:

      • 注销时如何删除这个cookie??
      【解决方案4】:

      我在我的应用中遇到了类似的情况。此解决方案适用于我使用 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();
      

      【讨论】:

      • 绝对是最好的答案之一。虽然,我个人不会使用 CookieHandler.setDefault,但这是我的选择(我讨厌影响整个系统)——我使用 okHttpClient.setCookieHandler(cookieManager)——其他替代方法是干扰拦截器
      猜你喜欢
      • 1970-01-01
      • 2011-09-18
      • 2019-11-25
      • 2014-11-16
      • 1970-01-01
      • 1970-01-01
      • 2012-09-14
      • 2012-01-21
      • 1970-01-01
      相关资源
      最近更新 更多