У меня была страница веб-просмотра, которая будет изменять отображаемый URL в зависимости от того, прошел ли пользователь аутентификацию. Проблема в том, что мой API прослушивателя проверки подлинности не прослушивает состояние проверки подлинности моего веб-просмотра. Это связано с тем, что файлы cookie, используемые WebView, не совпадают с файлами cookie, используемыми API-интерфейсом прослушивания аутентификации.
Мне нужно передать собранные cookie-файлы WebView onPageFinished
в API прослушивателя аутентификации
Вот фрагмент кода с WebView:
class MessageFragment : Fragment() {
val USER_AGENT_FAKE =
"Mozilla/5.0 (Linux; Android 4.1.1; Random User Agent) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19"
var uAuth : String = "0"
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val v: View = inflater.inflate(R.layout.fragment_messages, container, false)
val webView = v.findViewById<View>(R.id.webview_home) as WebView
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
view?.loadUrl(url)
return true
}
override fun onPageFinished(view: WebView?, url: String?) {
val cookieManager = CookieManager.getInstance()
val getUrl = view!!.url
cookieManager.setAcceptCookie(true)
var cookieValue : String = ""
var cookieId : String = ""
val cookieString = cookieManager.getCookie(getUrl)
if(!cookieString.isNullOrEmpty()) {
cookieString.splitIntoArray(";")
.filter { it.contains("csrftoken") }
.map{it.splitIntoArray("=")}
.forEach{cookieValue = it[1]}
cookieString.splitIntoArray(";")
.filter { it.contains("sessionid") }
.map{it.splitIntoArray("=")}
.forEach{cookieId = it[1]}
}
checkAuth(cookieValue, cookieId) // Pass csrftoken and sessionid values to checkauth function
super.onPageFinished(view, url)
}
}
val webSettings: WebSettings = webView.settings
webSettings.setAppCachePath(activity?.cacheDir?.absolutePath);
webSettings.allowFileAccess = true;
webSettings.setAppCacheEnabled(true)
webSettings.userAgentString = USER_AGENT_FAKE
webSettings.javaScriptEnabled = true
webSettings.domStorageEnabled = true
if (uAuth != "0") {
webView.loadUrl("http://random-domain-name-for-privacy.com/account/messages")
}
else
webView.loadUrl("http://random-domain-name-for-privacy.com/authListener")
return v
}
private fun checkAuth(cookieValue : String, cookieId: String) {
CookieInterceptor().getCookies(cookieValue, cookieId) //pass csrf and sessionid to cookieinterceptor
AuthHandlerApi().getAuthState().enqueue(object: Callback<List<AuthHandler>> {
override fun onFailure(call: Call<List<AuthHandler>>, t: Throwable) {
Toast.makeText(requireContext(), t.message, Toast.LENGTH_LONG).show()
}
override fun onResponse(call: Call<List<AuthHandler>>, response: Response<List<AuthHandler>>) {
val authReturn = response.body()
val authReturnString = authReturn.toString()
Toast.makeText(requireContext(), authReturnString, Toast.LENGTH_LONG).show()
if(authReturnString == "0") {
uAuth = "0"
}
else {
uAuth = "1"
}
}
})
}
private fun String.splitIntoArray(delimiter: String) =
this.split(delimiter).dropLastWhile { it.isEmpty() }.toTypedArray()
}
Также вот класс API:
const val BASE_URL = "http://some-random-domain-name-for-privacy.com/"
internal class CookieInterceptor : Interceptor {
@Volatile
private var cookie: String = ""
fun getCookies(cookieValue : String, cookieId: String) {
cookie = "csrftoken=$cookieValue;path=/;domain=.some-random-domain-name-for-privacy.com;HttpOnly;sessionid=$cookieId;path=/;domain=.some-random-domain-name-for-privacy.com;HttpOnly;"
}
override fun intercept(chain: Interceptor.Chain): Response = chain.run {
var request: Request = chain.request()
request = request.newBuilder()
.addHeader("Cookie", cookie)
.build()
return chain.proceed(request)
}
}
interface AuthHandlerApi {
@GET("authListener")
fun getAuthState() : Call<List<AuthHandler>>
companion object{
operator fun invoke() : AuthHandlerApi{
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(CookieInterceptor())
.build()
return Retrofit.Builder()
.baseUrl(BASE_URL)
.callFactory(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(AuthHandlerApi::class.java)
}
}
}
Я уже видел много подобных проблем, таких как это , это или это , но они в основном предназначены для передачи файлов cookie из Retrofit2 / Okhttp3 в Webview, но мне нужен обратный подход
РЕДАКТИРОВАТЬ : Я пытался добавить перехватчик для добавления файлов cookie из WebView, но API по-прежнему не может использовать файлы cookie для получения правильных результатов, так как он по-прежнему видит, что файлов cookie нет , Я следовал инструкциям по этому вопросу для перехватчика.