0
OkHttp 3 使用 PersistentCookieJar 自动处理 Cookie
配置
在 build.gradle 里面添加
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
dependencies {
compile 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
}
使用
ClearableCookieJar cookieJar =
new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.build();
OkHttp 2
如果是使用OkHttp 2的项目使用下面的代码
/*
* Copyright (c) 2015 Fran Montiel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class PersistentCookieStore implements CookieStore {
private static final String TAG = PersistentCookieStore.class
.getSimpleName();
// Persistence
private static final String SP_COOKIE_STORE = "cookieStore";
private static final String SP_KEY_DELIMITER = "|"; // Unusual char in URL
private static final String SP_KEY_DELIMITER_REGEX = "\\"
+ SP_KEY_DELIMITER;
private SharedPreferences sharedPreferences;
// In memory
private Map<URI, Set<HttpCookie>> allCookies;
public PersistentCookieStore(Context context) {
sharedPreferences = context.getSharedPreferences(SP_COOKIE_STORE,
Context.MODE_PRIVATE);
loadAllFromPersistence();
}
private void loadAllFromPersistence() {
allCookies = new HashMap<URI, Set<HttpCookie>>();
Map<String, ?> allPairs = sharedPreferences.getAll();
for (Entry<String, ?> entry : allPairs.entrySet()) {
String[] uriAndName = entry.getKey().split(SP_KEY_DELIMITER_REGEX,
2);
try {
URI uri = new URI(uriAndName[0]);
String encodedCookie = (String) entry.getValue();
HttpCookie cookie = new SerializableHttpCookie()
.decode(encodedCookie);
Set<HttpCookie> targetCookies = allCookies.get(uri);
if (targetCookies == null) {
targetCookies = new HashSet<HttpCookie>();
allCookies.put(uri, targetCookies);
}
// Repeated cookies cannot exist in persistence
// targetCookies.remove(cookie)
targetCookies.add(cookie);
} catch (URISyntaxException e) {
Log.w(TAG, e);
}
}
}
@Override
public synchronized void add(URI uri, HttpCookie cookie) {
uri = cookieUri(uri, cookie);
Set<HttpCookie> targetCookies = allCookies.get(uri);
if (targetCookies == null) {
targetCookies = new HashSet<HttpCookie>();
allCookies.put(uri, targetCookies);
}
targetCookies.remove(cookie);
targetCookies.add(cookie);
saveToPersistence(uri, cookie);
}
/**
* Get the real URI from the cookie "domain" and "path" attributes, if they
* are not set then uses the URI provided (coming from the response)
*
* @param uri
* @param cookie
* @return
*/
private static URI cookieUri(URI uri, HttpCookie cookie) {
URI cookieUri = uri;
if (cookie.getDomain() != null) {
// Remove the starting dot character of the domain, if exists (e.g: .domain.com -> domain.com)
String domain = cookie.getDomain();
if (domain.charAt(0) == '.') {
domain = domain.substring(1);
}
try {
cookieUri = new URI(uri.getScheme() == null ? "http"
: uri.getScheme(), domain,
cookie.getPath() == null ? "/" : cookie.getPath(), null);
} catch (URISyntaxException e) {
Log.w(TAG, e);
}
}
return cookieUri;
}
private void saveToPersistence(URI uri, HttpCookie cookie) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(uri.toString() + SP_KEY_DELIMITER + cookie.getName(),
new SerializableHttpCookie().encode(cookie));
editor.apply();
}
@Override
public synchronized List<HttpCookie> get(URI uri) {
return getValidCookies(uri);
}
@Override
public synchronized List<HttpCookie> getCookies() {
List<HttpCookie> allValidCookies = new ArrayList<HttpCookie>();
for (URI storedUri : allCookies.keySet()) {
allValidCookies.addAll(getValidCookies(storedUri));
}
return allValidCookies;
}
private List<HttpCookie> getValidCookies(URI uri) {
List<HttpCookie> targetCookies = new ArrayList<HttpCookie>();
// If the stored URI does not have a path then it must match any URI in
// the same domain
for (URI storedUri : allCookies.keySet()) {
// Check ith the domains match according to RFC 6265
if (checkDomainsMatch(storedUri.getHost(), uri.getHost())) {
// Check if the paths match according to RFC 6265
if (checkPathsMatch(storedUri.getPath(), uri.getPath())) {
targetCookies.addAll(allCookies.get(storedUri));
}
}
}
// Check it there are expired cookies and remove them
if (!targetCookies.isEmpty()) {
List<HttpCookie> cookiesToRemoveFromPersistence = new ArrayList<HttpCookie>();
for (Iterator<HttpCookie> it = targetCookies.iterator(); it
.hasNext(); ) {
HttpCookie currentCookie = it.next();
if (currentCookie.hasExpired()) {
cookiesToRemoveFromPersistence.add(currentCookie);
it.remove();
}
}
if (!cookiesToRemoveFromPersistence.isEmpty()) {
removeFromPersistence(uri, cookiesToRemoveFromPersistence);
}
}
return targetCookies;
}
/* http://tools.ietf.org/html/rfc6265#section-5.1.3
A string domain-matches a given domain string if at least one of the
following conditions hold:
o The domain string and the string are identical. (Note that both
the domain string and the string will have been canonicalized to
lower case at this point.)
o All of the following conditions hold:
* The domain string is a suffix of the string.
* The last character of the string that is not included in the
domain string is a %x2E (".") character.
* The string is a host name (i.e., not an IP address). */
private boolean checkDomainsMatch(String cookieHost, String requestHost) {
return requestHost.equals(cookieHost) || requestHost.endsWith("." + cookieHost);
}
/* http://tools.ietf.org/html/rfc6265#section-5.1.4
A request-path path-matches a given cookie-path if at least one of
the following conditions holds:
o The cookie-path and the request-path are identical.
o The cookie-path is a prefix of the request-path, and the last
character of the cookie-path is %x2F ("/").
o The cookie-path is a prefix of the request-path, and the first
character of the request-path that is not included in the cookie-
path is a %x2F ("/") character. */
private boolean checkPathsMatch(String cookiePath, String requestPath) {
return requestPath.equals(cookiePath) ||
(requestPath.startsWith(cookiePath) && cookiePath.charAt(cookiePath.length() - 1) == '/') ||
(requestPath.startsWith(cookiePath) && requestPath.substring(cookiePath.length()).charAt(0) == '/');
}
private void removeFromPersistence(URI uri, List<HttpCookie> cookiesToRemove) {
SharedPreferences.Editor editor = sharedPreferences.edit();
for (HttpCookie cookieToRemove : cookiesToRemove) {
editor.remove(uri.toString() + SP_KEY_DELIMITER
+ cookieToRemove.getName());
}
editor.apply();
}
@Override
public synchronized List<URI> getURIs() {
return new ArrayList<URI>(allCookies.keySet());
}
@Override
public synchronized boolean remove(URI uri, HttpCookie cookie) {
Set<HttpCookie> targetCookies = allCookies.get(uri);
boolean cookieRemoved = targetCookies != null && targetCookies
.remove(cookie);
if (cookieRemoved) {
removeFromPersistence(uri, cookie);
}
return cookieRemoved;
}
private void removeFromPersistence(URI uri, HttpCookie cookieToRemove) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(uri.toString() + SP_KEY_DELIMITER
+ cookieToRemove.getName());
editor.apply();
}
@Override
public synchronized boolean removeAll() {
allCookies.clear();
removeAllFromPersistence();
return true;
}
private void removeAllFromPersistence() {
sharedPreferences.edit().clear().apply();
}
}
Recommend
相关搜索关键词
Recent search keywords
- httpsonlineschoolal5com99214
- skillz
- JCMM
- 垃圾场
- monitoro.co
- monitoro
- insta
- -1 OR 3 422-422-1=0 0 0 1
- font_heading
- pretzelai
- Hackintosh
- A52S
- UPDATE ROM AC8227L - Android JCAC10003-OC2-V1.0.04R7-211119_1742
- -1 OR 3+422-422-1=0+0+0+1
- The Path to Reliability: How a QA Engineer Should Act in Non-Standard Situations
- -1 or 3 446-446-1=0 0 0 1 --
- WRP Android Video Player Pro" AND 7796=9605 AND "BfKb"="BfKb
- wrp android video player pro and 8553=8553-- woed
- AJG LONDON LTD
- All blooks in blocker
- fatbobman
- 5200L
- supermarket HTB
- netherlands
- https://m.youtube.com/watch?v=XylKubQFAkw#
- python数据处理
- moto
- MTK 8227L Android download
- w89941
- gold quest blooket
- gold quest
- Phoneinfoga
- Instrukcja
- nvst.ly
- nvstly
- trade hub
- madagascar
- smartos
- omnios
- 快
- proxy list.txt
- All blooket
- watch hentai app
- hentai stream app apk android
- hentai stream
- ssl pterodactyl
- BACKGROUND REMOVER
- code.daypilot.org
- drops
- YT9217B
- Loil
- 教你做任务之
- antranigv.am
- 转盘
- fbi
- 下列何者可能是黃禹錫造假研究成果的原因
- gaminator
- 程序员
- -1 OR 3+789-789-1=0+0+0+1 --
- @@flq3T
- glizzy
- wrp android video player pro) and 5868=4380-- htou
- fishy frenzy
- -1 or 2+47-47-1=0+0+0+1
- GitHub - glixzzy/blooket-hack: Multiple hacks that breaks the game
- 1050
- fx
- golden
- gloadal
- all the answers
- best kodi live tv
- spreadsho[
- gift
- -1" OR 3+854-854-1=0+0+0+1 --
- -1 OR 2+930-930-1=0+0+0+1
- truenas
- Automotive Lubricants Market
- keywords+AND+7652=7652
- 5767
- 盗刷信用卡商店
- virtual))) OR NOT 1220=3959#
- kahoot hack
- -1 or 3+446-446-1=0+0+0+1 --
- cabinet+maker+in+australia
- blooket+market+infininty+conis
- virtual or not 9584=4739
- cabinet maker in australia
- -1 or 2+786-786-1=0+0+0+1 --
- ketfgb0j
- download230413-2+32+13.rar
- 230413-2+32+13.rar
- chapter 20 samsung pt 2
- chapter 20 samsung
- greek iptv and 5423=5004-- xcpg
- https://www.ongraph.com/hire-nodejs-developers/
- keywords AND 7652=7652
- hard+reset
- how+to+unlock+blooks+in+blooket
- -1 or 2+706-706-1=0+0+0+1
- factory/vendor/phpunit/phpunit/src/util/php/eval-stdin.php/.env/fckeditor/editor/filemanager/connect
Android Studio 找不到com.github.franmontiel:persistentcookiejar
报 failed to resolve: com.github.franmontiel:persistentcookiejar:v1.0.1
看下配置这个添加没有
persistentcookiejar中保存的cookie没有保存本地, APP退出后就消失咯。
消失的这情况是因为服务端设置了cookie过期是时间的。让写API的人改下, 或者抓包看看。
之前一天掉线也是让server端解决的。