後付けで認証Cookieヘッダーを追加する方法を知る必要があります。リクエストインターセプターの使用などのアドバイスを見てきました。以下は私が試していることですが、これは正しいですか?まず、最初にセッションIDを取得するためにRequestAdatperが必要でした。これは、リクエストアダプタのビルダーによってのみ設定できます。しかし、そもそもセッションIDを取得するためだけにリクエストを行う必要がありました。セッションIDを取得するために1つ、取得後にもう1つ、2つのレストアダプターが必要ですか。私が本当に必要としているのは、取得後にCookieを設定するためのアダプター上のメソッドですが、そのようなメソッドではないようです。これは厄介になっています。後付けで認証Cookieを設定するにはどうすればよいですか?これはFAQまたはチュートリアルでは見られません。
RequestInterceptor requestInterceptor = new RequestInterceptor()
{
@Override
public void intercept(RequestFacade request) {
request.addHeader("Set-Cookie", "sessionId="+sessionIdentifier);
}
};
RestAdapter.Builder().setServer(serverURL)..setRequestIntercepter(requestIntercepter).build();
// but I don't have sessionId when this is first issued ???
インターセプターへの参照を保持し、それ自体をRestAdapter
のようにシングルトンとして扱います。
public class ApiHeaders implements RequestInterceptor {
private String sessionId;
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public void clearSessionId() {
sessionId = null;
}
@Override public void intercept(RequestFacade request) {
if (sessionId != null) {
request.setHeader(...);
}
}
}
ここで、認証呼び出しの後にsetSessionId
を呼び出すだけです。以降のすべてのリクエストにはヘッダーが含まれます。
あなたはこのようなクッキーを得ることができます
public 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("JSESSIONID")) {
Preference.getInstance().setSessionId(string);
}
}
}
}
これを使用してCookieHandlerを設定します
MyCookieManager myCookieManager = new MyCookieManager();
CookieHandler.setDefault(myCookieManager);
リクエストインターセプターでこのように使用します
String sessionId = preference.getSessionId();
if (sessionId != null)
requestFacade.addHeader(Cookie, sessionId);
ステップ1.応答ヘッダーを解析します。オーバーライドされたsuccess
メソッドでコールバック内でこのメソッドを呼び出します。
/**
* Method extracts cookie string from headers
* @param response with headers
* @return cookie string if present or null
*/
private String getCookieString(Response response) {
for (Header header : response.getHeaders()) {
if (null!= header.getName() && header.getName().equals("Set-Cookie")) {
return header.getValue();
}
}
return null;
}
ステップ2. CookieとRequestInterceptorインスタンスを保持する静的クラスまたはシングルトンを記述します。RequestInterceptorの内部でinterceptメソッドをオーバーライドして、Cookieをヘッダーに追加します。
public class RestAdapter {
private static String cookies;
public static String getCookies() {
return cookies;
}
public static void setCookies(String cookies) {
RestAdapter.cookies = cookies;
}
/**
* Injects cookies to every request
*/
private static final RequestInterceptor COOKIES_REQUEST_INTERCEPTOR = new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
if (null != cookies && cookies.length() > 0) {
request.addHeader("Cookie", cookies);
}
}
};
public static final RestInterface getService() {
return new RestAdapter.Builder()
.setEndpoint(Config.ENDPOINT)
.setRequestInterceptor(COOKIES_REQUEST_INTERCEPTOR)
.setConverter(new JacksonConverter())
.setLogLevel(RestAdapter.LogLevel.NONE)
.build()
.create(RestInterface.class);
}
}
@sbtgEの回答によると、いくつかの修正があります。 CookieHandler.getDefault()
はnullの可能性があるため、CookieManagerを使用します。
アプリのbuild.gradle:
dependencies {
...
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
}
レトロフィットの設定:
service = new Retrofit.Builder()
.baseUrl(/* your base URL */)
.addConverterFactory(/* your favourite converter */)
.client(
new OkHttpClient.Builder()
// this line is the important one:
.cookieJar(new JavaNetCookieJar(new CookieManager()))
.build())
.build()
.create(YourInterface.class);
Libを使用した簡単なソリューション。 _com.squareup.okhttp3:okhttp-urlconnection:3.2.0
_をコンパイルします。
JavaNetCookieJar jncj = new JavaNetCookieJar(CookieHandler.getDefault()); OkHttpClient.Builder().cookieJar(jncj).build();