Sincronize cookies entre visualizações da Web e aplicativos nativos para iOS e Android
Permita que as visualizações da Web estejam em sincronia com o aplicativo nativo por meio de cookies
Dlidar com Webviews em qualquer desenvolvimento de aplicativo nativo é sempre uma dor, especialmente quando queremos sincronizá-los de alguma forma. No entanto, às vezes é um mal necessário. Portanto, abaixo estão algumas maneiras de lidar com isso.
Existem três opções que podemos pensar
- Usando o parâmetro de consulta de URL (que é uma comunicação unidirecional)
- Usando JSBridge — conforme compartilhado por este artigo aqui (para Android)
- Usando Cookies — que é o foco deste artigo.
Aqui, forneço uma visão de como podemos passar cookies para ambos no iOS e no Android e em diferentes cenários.
- Acesse o cookie de uma API e compartilhe com um Webview
- Acesse o cookie de um Webview e compartilhe com outro Webview
- Crie um cookie do aplicativo nativo e compartilhe-o com um Webview
Para experimentar isso, criei um design de aplicativo simples, para iOS e Android, para referência.
Possui um servidor PHP (através do docker) que serve como API para configurar o cookie e páginas da Web para as webviews também para configurar o cookie e ler os cookies. Só precisa executá-lo usando
docker-compose up
GitHub – elye/demo_ios_android_webview_cookies_sync: Demonstração de como podemos sincronizar cookies da API…
Demonstração de como podemos sincronizar cookies da API, Native e Webview em outra Webview para iOS e Android. – GitHub…
github.com
Sincronização de cookies do Android
Havia várias maneiras de jogar com cookies no Android, conforme compartilhado no artigo abaixo.
Um conto sobre o gerenciamento de armazenamento de cookies do Android
O armazenamento de cookies é uma parte essencial do desenvolvimento do Android, amplamente utilizado na autenticação. Aqui estou compartilhando…
medium.com
O foco aqui é permitir que os Cookies sejam compartilhados entre o Nativo e o Webview. Por isso usamos a solução final compartilhada no blog acima, ou seja, usando a WebviewCookieHandler
abordagem.
1. Cookie do serviço de API para o WebView
Para buscar e manter os cookies definidos pelo serviço de API, precisamos definir o WebViewCookieHandler
através da OkHttp
instância que temos
valor privado webviewCookierHandler = WebviewCookieHandler() valor
privado okHttpClient = OkHttpClient()
.newBuilder()
.cookieJar( webviewCookieHandler )
.build()
Ao fazer isso, sempre que um cookie for definido pela API por meio da chamada da API usando a instância específica de okHttpClient
, o cookie será armazenado automaticamente e será usado pelo Webview iniciado pelo aplicativo.
2. Cookie do aplicativo nativo para o WebView
Às vezes, queremos criar manualmente o Cookie, para que as informações do Native App possam ser usadas por todos os WebViews lançados.
Crie manualmente o cookie e salve-o no formato webviewCookieHandler
.
val webviewCookieHandler = WebviewCookieHandler()// Cria o cookie val cookieBuilder = Cookie.Builder() val native_key = "native-cookie-set-key" cookieBuilder.name(native_key) cookieBuilder.value("this-is-set-by-native") cookieBuilder.domain ("10.0.2.2") val cookie = cookieBuilder.build()// Cria o domínio do cookie val httpUrlBuilder = HttpUrl.Builder() httpUrlBuilder.host("10.0.2.2") httpUrlBuilder.scheme("http") val httpUrl = httpUrlBuilder.build()webviewCookieHandler.saveCookies(httpUrl, listOf (cookie))
3. Cookie do WebView para outro WebView
Nada precisa ser feito aqui, pois todos os WebViews estão acessando e compartilhando o mesmo arquivo webviewCookieHandler
. Desde que estejam no mesmo domínio, os cookies são compartilhados entre eles.
Observação: para ChromeTab
Além de abrir um site usando o WebView, também podemos abrir usando o ChromeTab. Os cookies não são compartilhados entre o App e o Chrome, portanto, neste caso, não podemos passar os cookies.
Sincronização de cookies do iOS
Historicamente, o iOS está usando UIWebView
, que tem acesso HTTPCookieStorage
por padrão no futuro.
No entanto, a Apple está obsoleta UIWebView
e muda WKWebView
para melhor segurança e obsoleta UIWebView
em dezembro de 2020 .
WKWebView
não tem acesso a HTTPCookieStorage
, portanto, precisaremos aproveitar WKWebsiteDataStore
para sincronizar cookies.
1. Cookie do serviço de API para o WebView
Para buscar e manter os cookies definidos pelo serviço de API, precisamos definir HTTPCookieStorage
o URLSession
que é usado para buscar.
let request = URLRequest( url: URL.localApiServer, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10 )let session = URLSession.shared session.configuration.httpCookieAcceptPolicy = .always session.configuration.httpCookieStorage = HTTPCookieStorage.shared session.configuration.httpShouldSetCookies = true
Ao fazer isso, sempre que um cookie for definido pela API por meio da chamada da API usando o URLSession
, o cookie será armazenado automaticamente em HTTPCookieStorage
.
No entanto, como mencionado acima, esses cookies não podem ser acessados por nenhum WKWebView
. Existem 2 opções que podemos ir
A. Copiar manualmente para cada WKWebView
Se quisermos gerenciar cada WebView para garantir que apenas aqueles que desejamos que o Cookie o obtenham, podemos copiar manualmente os cookies para cada WebView que iniciamos conforme abaixo.
deixe cookies = HTTPCookieStorage.shared.cookies ?? [] para (cookie) em cookies { webView.configuration.websiteDataStore.httpCookieStore .setCookie(cookie) }let request = URLRequest(url: url) webView.load(request)
Isso é complicado, pois precisaremos fazer isso para cada WebView. Então temos a segunda opção
B. Copiar manualmente para WKWebsiteDataStore
Os WKWebsiteDataStore
cookies da loja que podem ser acessados por todos WKWebview
.
Abaixo está o código, ao buscar com sucesso o resultado da API, fazemos um loop manual e copiamos o código de HTTPCookie
para WKWebsiteDataStore
.
let dataTask = session.dataTask(with: request) { (data, response, error) in if error == nil { print("Success fetch!") guard let url = response?.url, let httpResponse = response as? HTTPURLResponse, deixe campos = httpResponse.allHeaderFields como? [String: String] else { return } let cookies = HTTPCookie.cookies( withResponseHeaderFields: fields, for: url) HTTPCookieStorage.shared.setCookies( cookies, for: url, mainDocumentURL: nil) for cookie em cookies { var cookieProperties = [HTTPCookiePropertyKey: Any]() cookieProperties[.name] = cookie.name cookieProperties[.value] = cookie.value cookieProperties[.domain] = cookie.domain cookieProperties[.path] = cookie. path cookieProperties[.version] = cookie.version cookieProperties[.expires] = Date().addingTimeInterval(31536000) let newCookie = HTTPCookie(properties: cookieProperties) // Precisa estar no encadeamento principal DispatchQueue.main.async { WKWebsiteDataStore.default() .httpCookieStore .setCookie(newCookie!, completionHandler: nil) } } }
Pode haver uma maneira mais elegante de transferir os dados em vez de fazer um loop por todos. Fique à vontade para compartilhar se houver. O acima é apenas um meio de mostrar que precisamos copiar os cookies.
Assim que WKWebwiteDataStore
tiver os cookies, WKWebView
terá acesso aos cookies.
2. Cookie do aplicativo nativo para o WebView
Às vezes, queremos criar manualmente o Cookie, para que as informações do Native App possam ser usadas por todos os WebViews lançados.
Crie manualmente o cookie e salve-o no formato WKWebsiteDataStore
.
let cookieName = "native-cookie-set-key" let cookieValue = "isto é definido por nativo" var cookieProperties = [HTTPCookiePropertyKey: Any]() cookieProperties[.name] = cookieName cookieProperties[.value] = cookieValue cookieProperties[.domain] = "127.0.0.1" cookieProperties[.path] = "" cookieProperties[.expires] = Date().addingTimeInterval(31536000)let newCookie = HTTPCookie(propriedades: cookieProperties)WKWebsiteDataStore.default().httpCookieStore.setCookie( newCookie!, completionHandler: {} )
3. Cookie do WebView para outro WebView
Nada precisa ser feito aqui, pois todos os WebViews estão acessando e compartilhando o mesmo arquivo WKWebsiteDataStore
. Desde que estejam no mesmo domínio, os cookies são compartilhados entre eles.
Nota: Para o Safari ViewController
Além de abrir um site usando WKWebView
, também podemos abrir usando o Safari ViewController. Os cookies não são compartilhados entre o App e o Safari, portanto, neste caso, não podemos passar os cookies.
É possível, mas use-o com cuidado
Embora o acima prove que o compartilhamento de cookies entre o aplicativo e o Webview é possível, ainda devemos usá-lo com moderação.
Qualquer compartilhamento de informações do App para a parte externa do App pode
- Sempre arrisque a segurança e a vulnerabilidade.
- A Apple ou o Google podem reforçar a segurança, arriscando-se a não funcionar no futuro
- O compartilhamento de cookies em todos os sites pode poluir alguns dados, se não for gerenciado corretamente, causando bugs difíceis de depurar.
Idealmente, tente evitar o uso do WebView, pois essa é a raiz de todos os desafios enfrentados para o desenvolvimento Web+App.