Browse Source

新增Cookie管理

drake 2 years ago
parent
commit
b41d4edb6c

+ 2 - 0
README.md

@@ -61,6 +61,8 @@ Net 3.x 版本使用OkHttp+协程实现, 可指定其OkHttp版本
 - AS日志插件/应用通知栏日志
 - 并发请求返回最快请求结果
 - 全局取消请求/自动取消请求
+- Https快速配置
+- Cookie管理
 - 强制缓存模式/自定义缓存Key/LRU缓存算法/缓存任何类型
 - 缓存+网络双重读取(预览模式实现)
 - 内置超强轮询器(计时器)

+ 27 - 0
docs/cookie.md

@@ -0,0 +1,27 @@
+Net使用的是OkHttp的Cookie管理方案(CookieJar), 并且提供持久化存储的Cookie管理实现(PersistentCookieJar)
+
+```kotlin
+class App : Application() {
+
+    override fun onCreate() {
+        super.onCreate()
+
+        NetConfig.initialize("http://github.com/", this) {
+            // 添加持久化Cookie
+            cookieJar(PersistentCookieJar(this@App))
+        }
+
+    }
+}
+```
+
+PersistentCookieJar可以手动增删Cookie
+
+| 函数 | 描述 |
+|-|-|
+| addAll | 添加Cookie |
+| getAll | 获取某个域名的所有Cookie |
+| remove | 删除某个域名下 |
+| clear | 删除应用全部Cookie |
+
+PersistentCookieJar使用数据库实现Cookies存储, 你可以指定`dbName`来创建不同的数据库让不同的客户端隔绝Cookie共享

+ 1 - 0
mkdocs.yml

@@ -67,6 +67,7 @@ nav:
   - 进度监听: progress.md
   - 取消请求: cancel.md
   - Https证书: https.md
+  - Cookie管理: cookie.md
   - 重复请求: unique.md
   - 缓存: cache.md
   - 自动搜索/筛选: debounce.md

+ 96 - 0
net/src/main/java/com/drake/net/cookie/PersistentCookieJar.kt

@@ -0,0 +1,96 @@
+package com.drake.net.cookie
+
+import android.content.ContentValues
+import android.content.Context
+import android.database.sqlite.SQLiteDatabase
+import android.database.sqlite.SQLiteOpenHelper
+import okhttp3.Cookie
+import okhttp3.CookieJar
+import okhttp3.HttpUrl
+
+/**
+ * 持久化存储Cookie
+ * @param dbName 数据库名称, 设置多个名称可以让不同的客户端共享不同的cookies
+ */
+class PersistentCookieJar(
+    val context: Context,
+    val dbName: String = "net_cookies",
+) : CookieJar {
+
+    private var sqlHelper: SQLiteOpenHelper = object : SQLiteOpenHelper(context, dbName, null, 1) {
+        override fun onCreate(db: SQLiteDatabase) {
+            db.execSQL("CREATE TABLE IF NOT EXISTS cookies (url TEXT, name TEXT, cookie TEXT, PRIMARY KEY(url, name))")
+        }
+
+        override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
+            db?.execSQL("DROP TABLE IF EXISTS cookies")
+        }
+    }
+
+    /**
+     * 添加Cookie到指定域名下
+     */
+    fun addAll(url: HttpUrl, cookies: List<Cookie>) {
+        val db = sqlHelper.writableDatabase
+        cookies.forEach { cookie ->
+            if (cookie.expiresAt > System.currentTimeMillis()) {
+                db.replace("cookies", null, ContentValues().apply {
+                    put("url", url.host)
+                    put("name", cookie.name)
+                    put("cookie", cookie.toString())
+                })
+            }
+        }
+    }
+
+    /**
+     * 获取指定域名下的所有Cookie
+     */
+    fun getAll(url: HttpUrl): List<Cookie> {
+        val db = sqlHelper.writableDatabase
+        db.rawQuery("SELECT * FROM cookies WHERE url = ?", arrayOf(url.host)).use { cursor ->
+            val cookies = mutableListOf<Cookie>()
+            while (cursor.moveToNext()) {
+                val cookieColumn = cursor.getString(cursor.getColumnIndex("cookie"))
+                val cookie = Cookie.parse(url, cookieColumn)
+                if (cookie != null) {
+                    if (cookie.expiresAt > System.currentTimeMillis()) {
+                        cookies.add(cookie)
+                    } else {
+                        db.delete("cookies", "url = ? AND name = ?", arrayOf(url.host, cookie.name))
+                    }
+                }
+            }
+            return cookies
+        }
+    }
+
+    /**
+     * 删除指定域名的所有Cookie
+     */
+    fun remove(url: HttpUrl) {
+        sqlHelper.writableDatabase.delete("cookies", "url = ?", arrayOf(url.host))
+    }
+
+    /**
+     * 删除指定域名下的指定cookie
+     */
+    fun remove(url: HttpUrl, cookieName: String) {
+        sqlHelper.writableDatabase.delete("cookies", "url = ? AND name = ?", arrayOf(url.host, cookieName))
+    }
+
+    /**
+     * 清除应用所有Cookie
+     */
+    fun clear() {
+        sqlHelper.writableDatabase.delete("cookies", null, null)
+    }
+
+    override fun loadForRequest(url: HttpUrl): List<Cookie> {
+        return getAll(url)
+    }
+
+    override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
+        addAll(url, cookies)
+    }
+}

+ 4 - 0
sample/src/main/java/com/drake/net/sample/base/App.kt

@@ -21,6 +21,7 @@ import com.chuckerteam.chucker.api.ChuckerCollector
 import com.chuckerteam.chucker.api.ChuckerInterceptor
 import com.drake.brv.BindingAdapter
 import com.drake.net.NetConfig
+import com.drake.net.cookie.PersistentCookieJar
 import com.drake.net.interceptor.LogRecordInterceptor
 import com.drake.net.okhttp.setConverter
 import com.drake.net.okhttp.setDebug
@@ -60,6 +61,9 @@ class App : Application() {
             // AndroidStudio OkHttp Profiler 插件输出网络日志
             addInterceptor(LogRecordInterceptor(BuildConfig.DEBUG))
 
+            // 添加持久化Cookie管理
+            cookieJar(PersistentCookieJar(this@App))
+
             // 通知栏监听网络日志
             if (BuildConfig.DEBUG) {
                 addInterceptor(