Передача собранных файлов cookie из веб-просмотра в Retrofit2 - PullRequest
0 голосов
/ 11 марта 2020

У меня была страница веб-просмотра, которая будет изменять отображаемый 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 нет , Я следовал инструкциям по этому вопросу для перехватчика.

...