feat: 保存 baiduid

This commit is contained in:
HuanCheng65 2023-02-18 17:30:48 +08:00
parent 9a59e2bac4
commit aea5ca4988
No known key found for this signature in database
GPG Key ID: E9031EF91A805148
7 changed files with 119 additions and 51 deletions

View File

@ -1,6 +1,5 @@
package com.huanchengfly.tieba.post.activities
import android.content.Intent
import android.graphics.Bitmap
import android.os.Bundle
import android.os.Handler
@ -13,6 +12,7 @@ import com.huanchengfly.tieba.post.api.retrofit.exception.getErrorMessage
import com.huanchengfly.tieba.post.fragments.WebViewFragment
import com.huanchengfly.tieba.post.interfaces.WebViewListener
import com.huanchengfly.tieba.post.utils.AccountUtil
import com.huanchengfly.tieba.post.utils.ClientUtils
import com.huanchengfly.tieba.post.utils.ThemeUtil
import com.huanchengfly.tieba.post.utils.Util
import kotlinx.coroutines.Dispatchers
@ -21,6 +21,8 @@ import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
class LoginActivity : BaseActivity(), WebViewListener {
private var isLoadingAccount = false
private var toolbar: Toolbar? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -48,49 +50,66 @@ class LoginActivity : BaseActivity(), WebViewListener {
toolbar!!.title = newTitle
}
// 从 Cookies 字符串解析出每个 Cookie
fun parseCookies(cookies: String): Map<String, String> {
val cookieMap = mutableMapOf<String, String>()
cookies.split(";").forEach {
val cookie = it.trim()
val cookieSplit = cookie.split("=").toMutableList()
if (cookieSplit.size > 1) {
val name = cookieSplit.removeFirst()
cookieMap[name] = cookieSplit.joinToString("=")
}
}
return cookieMap
}
override fun onPageFinished(view: WebView, url: String) {
if (isLoadingAccount) {
return
}
val cookieManager = CookieManager.getInstance()
val cookies = cookieManager.getCookie(url)
if (cookies != null) {
val bdussSplit = cookies.split("BDUSS=")
val sTokenSplit = cookies.split("STOKEN=")
if (bdussSplit.size > 1 && sTokenSplit.size > 1) {
val bduss = bdussSplit[1].split(";")[0]
val sToken = sTokenSplit[1].split(";")[0]
if (url.startsWith("https://tieba.baidu.com/index/tbwise/") || url.startsWith("https://tiebac.baidu.com/index/tbwise/")) {
val snackBar = Util.createSnackbar(view, "请稍后…", Snackbar.LENGTH_INDEFINITE)
snackBar.show()
launch {
AccountUtil.fetchAccountFlow(bduss, sToken, cookies)
.flowOn(Dispatchers.IO)
.catch { e ->
snackBar.setText("登录失败 ${e.getErrorMessage()}")
val cookiesStr = cookieManager.getCookie(url) ?: ""
val cookies = parseCookies(cookiesStr)
val bduss = cookies["BDUSS"]
val sToken = cookies["STOKEN"]
val baiduId = cookies["BAIDUID"]
if (url.startsWith("https://tieba.baidu.com/index/tbwise/") || url.startsWith("https://tiebac.baidu.com/index/tbwise/")) {
if (bduss == null || sToken == null) {
return
}
if (!baiduId.isNullOrEmpty() && ClientUtils.baiduId.isNullOrEmpty()) launch {
ClientUtils.saveBaiduId(
this@LoginActivity,
baiduId
)
}
val snackBar = Util.createSnackbar(view, "请稍后…", Snackbar.LENGTH_INDEFINITE)
isLoadingAccount = true
snackBar.show()
launch {
AccountUtil.fetchAccountFlow(bduss, sToken, cookiesStr)
.flowOn(Dispatchers.IO)
.catch { e ->
snackBar.setText("登录失败 ${e.getErrorMessage()}")
isLoadingAccount = false
view.loadUrl("https://wappass.baidu.com/passport?login&u=https%3A%2F%2Ftieba.baidu.com%2Findex%2Ftbwise%2Fmine")
handler.postDelayed({ snackBar.dismiss() }, 1500)
}
.flowOn(Dispatchers.Main)
.collect { account ->
AccountUtil.newAccount(account.uid, account) {
isLoadingAccount = false
if (it) {
AccountUtil.switchUser(this@LoginActivity, account.id)
snackBar.setText("登录成功,即将跳转")
} else {
snackBar.setText("登录失败 未知错误")
view.loadUrl("https://wappass.baidu.com/passport?login&u=https%3A%2F%2Ftieba.baidu.com%2Findex%2Ftbwise%2Fmine")
handler.postDelayed({ snackBar.dismiss() }, 1500)
}
.flowOn(Dispatchers.Main)
.collect { account ->
AccountUtil.newAccount(account.uid, account) {
if (it) {
AccountUtil.switchUser(this@LoginActivity, account.id)
snackBar.setText("登录成功,即将跳转")
handler.postDelayed({
snackBar.dismiss()
finish()
startActivity(
Intent(
this@LoginActivity,
UpdateInfoActivity::class.java
)
)
}, 1500)
} else {
snackBar.setText("登录失败 未知错误")
}
}
}
}
}
}
}
}
}

View File

@ -30,8 +30,8 @@ object Header {
const val DROP_HEADERS = "drop_headers"
const val NO_COMMON_PARAMS = "no_common_params"
const val ADD_COOKIE = "add_cookie"
const val ADD_COOKIE_FALSE = "false"
const val ADD_WEB_COOKIE = "add_cookie"
const val ADD_WEB_COOKIE_FALSE = "false"
const val ACCEPT_LANGUAGE = "Accept-Language"
const val ACCEPT_LANGUAGE_VALUE = "zh-CN,zh;q=0.9"

View File

@ -9,9 +9,10 @@ import com.huanchengfly.tieba.post.api.models.OAID
import com.huanchengfly.tieba.post.api.retrofit.adapter.DeferredCallAdapterFactory
import com.huanchengfly.tieba.post.api.retrofit.adapter.FlowCallAdapterFactory
import com.huanchengfly.tieba.post.api.retrofit.converter.gson.GsonConverterFactory
import com.huanchengfly.tieba.post.api.retrofit.interceptors.AddCookieInterceptor
import com.huanchengfly.tieba.post.api.retrofit.interceptors.AddWebCookieInterceptor
import com.huanchengfly.tieba.post.api.retrofit.interceptors.CommonHeaderInterceptor
import com.huanchengfly.tieba.post.api.retrofit.interceptors.CommonParamInterceptor
import com.huanchengfly.tieba.post.api.retrofit.interceptors.CookieInterceptor
import com.huanchengfly.tieba.post.api.retrofit.interceptors.DropInterceptor
import com.huanchengfly.tieba.post.api.retrofit.interceptors.FailureResponseInterceptor
import com.huanchengfly.tieba.post.api.retrofit.interceptors.ForceLoginInterceptor
@ -98,7 +99,8 @@ object RetrofitTiebaApi {
Header.CHARSET to { "UTF-8" },
Header.HOST to { "tieba.baidu.com" },
),
AddCookieInterceptor)
AddWebCookieInterceptor
)
}
val MINI_TIEBA_API: MiniTiebaApi by lazy {
@ -247,6 +249,7 @@ object RetrofitTiebaApi {
addInterceptor(DropInterceptor)
addInterceptor(ProtoFailureResponseInterceptor)
addInterceptor(ForceLoginInterceptor)
addInterceptor(CookieInterceptor)
addInterceptor(sortAndSignInterceptor)
connectionPool(connectionPool)
}.build())

View File

@ -5,7 +5,7 @@ import com.huanchengfly.tieba.post.utils.AccountUtil
import okhttp3.Interceptor
import okhttp3.Response
object AddCookieInterceptor : Interceptor {
object AddWebCookieInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
var headers = request.headers
@ -13,11 +13,11 @@ object AddCookieInterceptor : Interceptor {
val body = request.body
var addCookie = true
val addCookieHeader = headers[Header.ADD_COOKIE]
val addCookieHeader = headers[Header.ADD_WEB_COOKIE]
if (addCookieHeader != null) {
if (addCookieHeader == Header.ADD_COOKIE_FALSE) addCookie = false
if (addCookieHeader == Header.ADD_WEB_COOKIE_FALSE) addCookie = false
headers = headers.newBuilder()
.removeAll(Header.ADD_COOKIE)
.removeAll(Header.ADD_WEB_COOKIE)
.build()
}

View File

@ -0,0 +1,33 @@
package com.huanchengfly.tieba.post.api.retrofit.interceptors
import com.huanchengfly.tieba.post.App
import com.huanchengfly.tieba.post.utils.ClientUtils
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import okhttp3.Interceptor
import okhttp3.Response
object CookieInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val response = chain.proceed(chain.request())
val cookies = response.headers("Set-Cookie")
if (cookies.isNotEmpty()) {
cookies.forEach {
val cookieName = it.substringBefore("=")
val cookieValue = it.substringAfter("=").substringBefore(";")
if (cookieName.equals(
"BAIDUID",
ignoreCase = true
) && ClientUtils.baiduId.isNullOrEmpty()
) {
MainScope().launch {
ClientUtils.saveBaiduId(App.INSTANCE, cookieValue)
}
}
}
}
return response
}
}

View File

@ -117,7 +117,7 @@ interface WebTiebaApi {
): Deferred<ApiResult<ForumBean>>
@Headers(
"${Header.ADD_COOKIE}: ${Header.ADD_COOKIE_FALSE}"
"${Header.ADD_WEB_COOKIE}: ${Header.ADD_WEB_COOKIE_FALSE}"
)
@GET("/mo/q/newmoindex?need_user=1")
fun myInfo(
@ -125,7 +125,7 @@ interface WebTiebaApi {
): Call<MyInfoBean>
@Headers(
"${Header.ADD_COOKIE}: ${Header.ADD_COOKIE_FALSE}"
"${Header.ADD_WEB_COOKIE}: ${Header.ADD_WEB_COOKIE_FALSE}"
)
@GET("/mo/q/newmoindex?need_user=1")
fun myInfoAsync(
@ -133,7 +133,7 @@ interface WebTiebaApi {
): Deferred<ApiResult<MyInfoBean>>
@Headers(
"${Header.ADD_COOKIE}: ${Header.ADD_COOKIE_FALSE}"
"${Header.ADD_WEB_COOKIE}: ${Header.ADD_WEB_COOKIE_FALSE}"
)
@GET("/mo/q/newmoindex?need_user=1")
fun myInfoFlow(

View File

@ -14,14 +14,17 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
object ClientUtils {
const val CLIENT_ID = "client_id"
const val SAMPLE_ID = "sample_id"
private const val CLIENT_ID = "client_id"
private const val SAMPLE_ID = "sample_id"
private const val BAIDU_ID = "baidu_id"
private val clientIdKey = stringPreferencesKey(CLIENT_ID)
private val sampleIdKey = stringPreferencesKey(SAMPLE_ID)
private val baiduIdKey = stringPreferencesKey(BAIDU_ID)
var clientId: String? = null
var sampleId: String? = null
var baiduId: String? = null
fun init(context: Context) {
CoroutineScope(Dispatchers.IO).launch {
@ -31,10 +34,20 @@ object ClientUtils {
sampleId = withContext(Dispatchers.IO) {
context.dataStore.data.map { it[sampleIdKey] }.firstOrNull()
}
baiduId = withContext(Dispatchers.IO) {
context.dataStore.data.map { it[baiduIdKey] }.firstOrNull()
}
sync(context)
}
}
suspend fun saveBaiduId(context: Context, id: String) {
baiduId = id
context.dataStore.edit {
it[baiduIdKey] = id
}
}
private suspend fun save(context: Context, clientId: String, sampleId: String) {
context.dataStore.edit {
it[clientIdKey] = clientId