Hi, everyone.I have a question about Android and Okhttp3.
I implemented session login using Okhttp3 (3.10.0) and PersistentCookieStore, but I can't log in on Android 10 without any problems (Log in ). When I checked the communication using Stetho, it seems that the Set-Cookie in the Http header did not work on Android 10. (*On Android 7 and regular JRE 11, the Set-Cookie worked and returned as a cookie, and I was able to log in correctly.)
The surrounding code and communication debugs are listed below.Please let me know the cause and solution.compileSdkVersion29
buildToolsVersion "29.0.2"
minSdkVersion22
targetSdkVersion29
//Function that performs login for convenience
funloginTest(){
API.login("serverId", "my_password")
}
object API {
private valgson=Gson()
var loggedIn=false
varserverId=""
// LoginResponse and AbstractResponse are response data classes
fun login(serverId:String, password:String): LoginResponse {
try{
val response = Http.postXWwwFormUrlEncoded(
"https://x.mirm.jp/authenticate", mapOf(
"serverId" to URLEncoder.encode(serverId),
"password" to URLEncoder.encode (password),
"_csrf" to getCsrf()// Get CSRF token once for login
)
?: return LoginResponse (AbstractResponse.STATUS_ERROR, LoginResponse.LOGIN_STATUS_FAILED)
if(response.contains("Expired server removed.")) return LoginResponse (AbstractResponse.STATUS_SUCCEEDED, LoginResponse.LOGIN_STATUS_DELETED_SERVER)
if(response.contains("Delete Server button removed)US>") return LoginResponse (AbstractResponse.STATUS_SUCCEED, LoginResponse.LOGIN_STATUS_USER_DELETED)
return response.contents("MiRm|Control Panel").let{
if(it){
This.loggedIn=true
This.serverId = serverId
return LoginResponse (AbstractResponse.STATUS_SUCCEED, LoginResponse.LOGIN_STATUS_SUCCEED)
} else{
return LoginResponse (AbstractResponse.STATUS_SUCCEED, LoginResponse.LOGIN_STATUS_FAILED)
}
}
} catch(e:MissingRequestException){
if(e.errorCode==503){
return LoginResponse (AbstractResponse.STATUS_OUT_OF_SERVICE, LoginResponse.LOGIN_STATUS_FAILED)
}
} catch(e:Exception){
e.printStackTrace()
}
return LoginResponse (AbstractResponse.STATUS_ERROR, LoginResponse.LOGIN_STATUS_FAILED)
}
private fungetCsrf(): String {
val document = Jgroup.parse(Http.get("https://x.mirm.jp/login"))
return document.select(" input [name=_csrf ]").attr("value") // Returns CSRF Token
}
}
object Http{
private constant USER_AGENT="MiRmGo/0.0.1"
private value client —OkHttpClient
private val heads —Headers
init{
valcookieHandler=CookieManager (PersistentCookieStore (MyApplication.getApplication()); CookiePolicy.ACCEPT_ALL)
client=OkHttpClient.Builder()
.cookieJar (JavaNetCookieJar(cookieHandler))
.addNetworkInterceptor(StethoInterceptor())
.build()
headers=Headers.Builder()
.set("Accept", "text/html", application/xhtml+xml, application/xml;q=0.9, image/webp, image/apng, */*;q=0.8")
.set ("User-agent", USER_AGENT)
.set("Accept-Language", "ja, en-US;q=0.9, en;q=0.8")
.set("Connection", "keep-alive")
.set("Refer", "https://x.mirm.jp/login")
.set ("Origin", "https://x.mirm.jp")
.build()
}
funpostXWwwFormUrlEncoded (url: String, data: Map<String, String>): String?{
val postData=data.let{
var str=""
it.forEach{
str+="${it.key}=${URLEncoder.encode(it.value, StandardCharsets.UTF_8.name())}&"
}
str.removeSuffix("&")
}
val requestBody = RequestBody.create (MediaType.parse("application/x-www-form-urlencoded"), postData)
val request = Request.Builder()
.url(url)
.headers (headers)
.header("Content-Length", postData.length.toString())
.header("Content-Type", "application/x-www-form-urlencoded")
.post(requestBody)
.build()
val response=client.newCall(request).execute()
if(!response.isSuccessful)throw MissingRequestException(response.code())
return response.body()?string()
}
funget(url:String, data:Map<String,String>=mapOf())—String?{
var postUrl = url
if(data.isNotEmpty()){
postUrl+="?"
data.forEach {
postUrl+="${it.key}=${it.value}&"
}
postUrl=postUrl.removeSuffix("&")
}
val request = Request.Builder()
.url(postUrl)
.headers (headers)
.build()
val response=client.newCall(request).execute()
if(!response.isSuccessful)throw MissingRequestException(response.code())
return response.body()?string()
}
}
Set-Cookie:(...);HttpOnly
I guess this is the point.
HTTP is disabled by default from Android 9 (API 28).Official:Modifying Framework Security
Therefore,
Or
required.
610 GDB gets version error when attempting to debug with the Presense SDK (IDE)
617 Uncaught (inpromise) Error on Electron: An object could not be cloned
911 When building Fast API+Uvicorn environment with PyInstaller, console=False results in an error
572 rails db:create error: Could not find mysql2-0.5.4 in any of the sources
© 2024 OneMinuteCode. All rights reserved.