改造和授权饼干
Posted
技术标签:
【中文标题】改造和授权饼干【英文标题】:RETROFIT & AUTH COOKIE 【发布时间】:2014-02-10 06:29:05 【问题描述】:我需要知道如何在改造中添加授权 cookie 标头。我已经看到了使用请求拦截器等的建议。下面是我正在尝试的,但这是正确的吗?首先,我已经需要一个 RequestAdatper 来第一次获取会话 ID。这只能由请求适配器的构建器设置。但我首先需要提出一个请求来获取会话 ID。我是否需要两个休息适配器,一个来获取 sessionId,另一个在我获得它之后。我真正需要的是适配器上的一种方法来设置cookie,但它似乎不是这样的方法。这越来越尴尬了。如何在改造中设置授权 cookie?我在常见问题解答或教程中没有看到这一点。
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 ???
【问题讨论】:
我的应用可能不需要这个。但这是一个很好的问题,所以请有人回答。 你最终做了什么,因为答案中的代码令人困惑......试图将它包含在我调用我的请求的同一页面中。 【参考方案1】:保留对拦截器的引用,并将其视为单例,就像您自己是 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
。所有后续请求都将包含标头。
【讨论】:
试图弄清楚如何从类外部调用 setSessionId...ApiHeaders.setSessionId 不是方法... @Lion789 你需要一个静态的 setSessionId。 @Jake Wharton:我们如何从响应中获取 sessionId? 这将取决于您的服务器如何将它们发回。 @KailashDabhi 你只需要使用拦截器并覆盖新方法!【参考方案2】:你可以像这样获取cookies
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);
【讨论】:
工作得很好!谢谢@Chetna!【参考方案3】:第 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 内部覆盖拦截方法以将您的 cookie 添加到 Header。
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);
【讨论】:
【参考方案4】:根据@sbtgE 的回答,但有一些更正。 CookieHandler.getDefault()
可能为空,所以我使用 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);
【讨论】:
断线时如何清除cookie。【参考方案5】:使用 lib 的简单解决方案。编译com.squareup.okhttp3:okhttp-urlconnection:3.2.0
。
JavaNetCookieJar jncj = new JavaNetCookieJar(CookieHandler.getDefault());
OkHttpClient.Builder().cookieJar(jncj).build();
【讨论】:
以上是关于改造和授权饼干的主要内容,如果未能解决你的问题,请参考以下文章
Spring cloud微服务安全实战-6-5jwt改造之日志及错误处理