如何在Blazor Server登录页面中使“记住我”功能在Android WebView中稳定工作?

huangapple go评论104阅读模式
英文:

How to make the 'Remember Me' function in Blazor Server login page work consistently in Android WebView?

问题

在我的Blazor Server应用程序中,我使用了内置的AuthenticationStateProvider服务进行Blazor Server的身份验证。该服务的登录页面具有正常工作的“记住我”功能。

在我的Android应用程序中,我使用WebView显示Blazor Server网站。

MainActivity.java:

  1. import android.annotation.SuppressLint;
  2. import android.graphics.Bitmap;
  3. import android.view.View;
  4. import android.webkit.CookieManager;
  5. import android.webkit.WebChromeClient;
  6. import android.webkit.WebSettings;
  7. import android.webkit.WebView;
  8. import android.webkit.WebViewClient;
  9. import android.widget.ProgressBar;
  10. import androidx.appcompat.app.AppCompatActivity;
  11. import android.os.Bundle;
  12. public class MainActivity extends AppCompatActivity {
  13. private WebView webView;
  14. private ProgressBar progressBar;
  15. @SuppressLint("SetJavaScriptEnabled")
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.activity_main);
  20. webView = findViewById(R.id.webview);
  21. progressBar = findViewById(R.id.progressBar);
  22. // 配置WebView设置
  23. WebSettings webSettings = webView.getSettings();
  24. webSettings.setJavaScriptEnabled(true);
  25. webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
  26. CookieManager.getInstance().setAcceptCookie(true);
  27. CookieManager.getInstance().acceptThirdPartyCookies(webView);
  28. // 设置WebView客户端
  29. webView.setWebViewClient(new WebViewClient() {
  30. @Override
  31. public void onPageStarted(WebView view, String url, Bitmap favicon) {
  32. super.onPageStarted(view, url, favicon);
  33. progressBar.setVisibility(View.VISIBLE);
  34. webView.setVisibility(View.GONE);
  35. }
  36. @Override
  37. public void onPageFinished(WebView view, String url) {
  38. super.onPageFinished(view, url);
  39. progressBar.setVisibility(View.GONE);
  40. webView.setVisibility(View.VISIBLE);
  41. }
  42. });
  43. webView.setWebChromeClient(new WebChromeClient() {
  44. public void onProgressChanged(WebView view, int progress) {
  45. progressBar.setProgress(progress);
  46. }
  47. });
  48. // 加载网站
  49. webView.loadUrl("URL HERE");
  50. }
  51. @Override
  52. public void onBackPressed() {
  53. // 处理WebView内的返回按钮按下
  54. if (webView.canGoBack()) {
  55. webView.goBack();
  56. } else {
  57. super.onBackPressed();
  58. }
  59. }
  60. }

添加到AndroidManifest.xml:

  1. <uses-permission android:name="android.permission.INTERNET"/>

activity_main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. tools:context=".MainActivity">
  7. <WebView
  8. android:id="@+id/webview"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent"
  11. android:visibility="gone" />
  12. <ProgressBar
  13. android:id="@+id/progressBar"
  14. style="?android:attr/progressBarStyleHorizontal"
  15. android:layout_width="match_parent"
  16. android:layout_height="wrap_content"
  17. android:layout_centerVertical="true"
  18. android:layout_centerHorizontal="true"
  19. android:indeterminate="false"
  20. android:max="100"
  21. android:progress="0"
  22. android:visibility="gone" />
  23. </RelativeLayout>

当我通过WebView应用程序登录时,“记住我”功能在100次尝试中只有1次成功,并将凭据存储在我的手机上的应用数据中。我知道这是因为:

  • 即使在Google Chrome中清除浏览器历史记录后,我仍然保持登录状态。
  • 即使清除应用程序的缓存存储后,我仍然保持登录状态。
  • 当我清除应用程序的所有数据(应用信息 -> 存储 -> 清除数据)时,我不再保持登录状态。

在其他99次尝试中,它不会记住登录,当我再次打开WebView应用程序时,我必须重新登录。

如何使此功能在100次尝试中都能正常工作?我从未弄清楚应用程序何时保存登录凭据以及何时不保存...

我已激活了JavaScript和(第三方)Cookie。问题仍未解决。

英文:

I have a Blazor Server app where I use the build-in AuthenticationStateProvider service for Blazor Server. The login page of this service has a remember me function that works properly.

Within my Android App I show the Blazor Server website with a WebView

MainActivity.Java:

  1. import android.annotation.SuppressLint;
  2. import android.graphics.Bitmap;
  3. import android.view.View;
  4. import android.webkit.CookieManager;
  5. import android.webkit.WebChromeClient;
  6. import android.webkit.WebSettings;
  7. import android.webkit.WebView;
  8. import android.webkit.WebViewClient;
  9. import android.widget.ProgressBar;
  10. import androidx.appcompat.app.AppCompatActivity;
  11. import android.os.Bundle;
  12. public class MainActivity extends AppCompatActivity {
  13. private WebView webView;
  14. private ProgressBar progressBar;
  15. @SuppressLint(&quot;SetJavaScriptEnabled&quot;)
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.activity_main);
  20. webView = findViewById(R.id.webview);
  21. progressBar = findViewById(R.id.progressBar);
  22. // Configure WebView settings
  23. WebSettings webSettings = webView.getSettings();
  24. webSettings.setJavaScriptEnabled(true);
  25. webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
  26. CookieManager.getInstance().setAcceptCookie(true);
  27. CookieManager.getInstance().acceptThirdPartyCookies(webView);
  28. // Set WebView clients
  29. webView.setWebViewClient(new WebViewClient() {
  30. @Override
  31. public void onPageStarted(WebView view, String url, Bitmap favicon) {
  32. super.onPageStarted(view, url, favicon);
  33. progressBar.setVisibility(View.VISIBLE);
  34. webView.setVisibility(View.GONE);
  35. }
  36. @Override
  37. public void onPageFinished(WebView view, String url) {
  38. super.onPageFinished(view, url);
  39. progressBar.setVisibility(View.GONE);
  40. webView.setVisibility(View.VISIBLE);
  41. }
  42. });
  43. webView.setWebChromeClient(new WebChromeClient() {
  44. public void onProgressChanged(WebView view, int progress) {
  45. progressBar.setProgress(progress);
  46. }
  47. });
  48. // Load the website
  49. webView.loadUrl(&quot;URL HERE&quot;);
  50. }
  51. @Override
  52. public void onBackPressed() {
  53. // Handle back button press inside WebView
  54. if (webView.canGoBack()) {
  55. webView.goBack();
  56. } else {
  57. super.onBackPressed();
  58. }
  59. }
  60. }

Added to the AndroidManifest.xml:
&lt;uses-permission android:name=&quot;android.permission.INTERNET&quot;/&gt;

Activity_main.xml

  1. &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
  2. &lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
  3. xmlns:tools=&quot;http://schemas.android.com/tools&quot;
  4. android:layout_width=&quot;match_parent&quot;
  5. android:layout_height=&quot;match_parent&quot;
  6. tools:context=&quot;.MainActivity&quot;&gt;
  7. &lt;WebView
  8. android:id=&quot;@+id/webview&quot;
  9. android:layout_width=&quot;match_parent&quot;
  10. android:layout_height=&quot;match_parent&quot;
  11. android:visibility=&quot;gone&quot; /&gt;
  12. &lt;ProgressBar
  13. android:id=&quot;@+id/progressBar&quot;
  14. style=&quot;?android:attr/progressBarStyleHorizontal&quot;
  15. android:layout_width=&quot;match_parent&quot;
  16. android:layout_height=&quot;wrap_content&quot;
  17. android:layout_centerVertical=&quot;true&quot;
  18. android:layout_centerHorizontal=&quot;true&quot;
  19. android:indeterminate=&quot;false&quot;
  20. android:max=&quot;100&quot;
  21. android:progress=&quot;0&quot;
  22. android:visibility=&quot;gone&quot; /&gt;
  23. &lt;/RelativeLayout&gt;

When I login via the WebView app, the Remember Me function is working 1 out of 100 times and stores the credentials local on my phone within the app data. I know this because:

  • I remain logged in when I clear my browser history on Google Chrome
  • I remain logged in when I clear the cache storage of the app
  • I am no longer logged in when I clear all data of the app (App info -&gt; Storage -&gt; Clear Data)

The other 99 out of 100 times it does not remember the login and when I open de WebView app again I have to login again.

How can I make this functionality work 100 out of 100 times? I never got to figure out when the app does save the login credentials and when it does not...

I activated JavaScript and (third party) coockies. Problem still not solved.

答案1

得分: 0

我发现 WebView 应用程序并不总是正确同步存储的 Cookie。为了修复这个问题,将以下代码添加到 MainActivity 中:

  1. webView.setWebViewClient(new WebViewClient() {
  2. @Override
  3. public void onPageFinished(WebView view, String url) {
  4. CookieManager.getInstance().flush();
  5. }
  6. });

完整代码:

  1. import android.annotation.SuppressLint;
  2. import android.graphics.Bitmap;
  3. import android.view.View;
  4. import android.webkit.CookieManager;
  5. import android.webkit.WebChromeClient;
  6. import android.webkit.WebSettings;
  7. import android.webkit.WebView;
  8. import android.webkit.WebViewClient;
  9. import android.widget.ProgressBar;
  10. import androidx.appcompat.app.AppCompatActivity;
  11. import android.os.Bundle;
  12. public class MainActivity extends AppCompatActivity {
  13. private WebView webView;
  14. private ProgressBar progressBar;
  15. @SuppressLint("SetJavaScriptEnabled")
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.activity_main);
  20. webView = findViewById(R.id.webview);
  21. progressBar = findViewById(R.id.progressBar);
  22. // 配置 WebView 设置
  23. WebSettings webSettings = webView.getSettings();
  24. webSettings.setJavaScriptEnabled(true);
  25. webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
  26. CookieManager.getInstance().setAcceptCookie(true);
  27. CookieManager.getInstance().acceptThirdPartyCookies(webView);
  28. // 设置 WebView 客户端
  29. webView.setWebViewClient(new WebViewClient() {
  30. @Override
  31. public void onPageStarted(WebView view, String url, Bitmap favicon) {
  32. super.onPageStarted(view, url, favicon);
  33. progressBar.setVisibility(View.VISIBLE);
  34. webView.setVisibility(View.GONE);
  35. }
  36. @Override
  37. public void onPageFinished(WebView view, String url) {
  38. super.onPageFinished(view, url);
  39. CookieManager.getInstance().flush();
  40. progressBar.setVisibility(View.GONE);
  41. webView.setVisibility(View.VISIBLE);
  42. }
  43. });
  44. webView.setWebChromeClient(new WebChromeClient() {
  45. public void onProgressChanged(WebView view, int progress) {
  46. progressBar.setProgress(progress);
  47. }
  48. });
  49. // 加载网站
  50. webView.loadUrl("在此处输入网址");
  51. }
  52. @Override
  53. public void onBackPressed() {
  54. // 处理 WebView 内部的返回按钮按下事件
  55. if (webView.canGoBack()) {
  56. webView.goBack();
  57. } else {
  58. super.onBackPressed();
  59. }
  60. }
  61. }
英文:

I found out the WebView App is not always syncing the stored cookies correctly. To fix this add the following code to the MainActivity:

  1. webView.setWebViewClient(new WebViewClient() {
  2. @Override
  3. public void onPageFinished(WebView view, String url) {
  4. CookieManager.getInstance().flush();
  5. }
  6. }

full code:

  1. import android.annotation.SuppressLint;
  2. import android.graphics.Bitmap;
  3. import android.view.View;
  4. import android.webkit.CookieManager;
  5. import android.webkit.WebChromeClient;
  6. import android.webkit.WebSettings;
  7. import android.webkit.WebView;
  8. import android.webkit.WebViewClient;
  9. import android.widget.ProgressBar;
  10. import androidx.appcompat.app.AppCompatActivity;
  11. import android.os.Bundle;
  12. public class MainActivity extends AppCompatActivity {
  13. private WebView webView;
  14. private ProgressBar progressBar;
  15. @SuppressLint(&quot;SetJavaScriptEnabled&quot;)
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.activity_main);
  20. webView = findViewById(R.id.webview);
  21. progressBar = findViewById(R.id.progressBar);
  22. // Configure WebView settings
  23. WebSettings webSettings = webView.getSettings();
  24. webSettings.setJavaScriptEnabled(true);
  25. webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
  26. CookieManager.getInstance().setAcceptCookie(true);
  27. CookieManager.getInstance().acceptThirdPartyCookies(webView);
  28. // Set WebView clients
  29. webView.setWebViewClient(new WebViewClient() {
  30. @Override
  31. public void onPageStarted(WebView view, String url, Bitmap favicon) {
  32. super.onPageStarted(view, url, favicon);
  33. progressBar.setVisibility(View.VISIBLE);
  34. webView.setVisibility(View.GONE);
  35. }
  36. @Override
  37. public void onPageFinished(WebView view, String url) {
  38. super.onPageFinished(view, url);
  39. CookieManager.getInstance().flush();
  40. progressBar.setVisibility(View.GONE);
  41. webView.setVisibility(View.VISIBLE);
  42. }
  43. });
  44. webView.setWebChromeClient(new WebChromeClient() {
  45. public void onProgressChanged(WebView view, int progress) {
  46. progressBar.setProgress(progress);
  47. }
  48. });
  49. // Load the website
  50. webView.loadUrl(&quot;URL HERE&quot;);
  51. }
  52. @Override
  53. public void onBackPressed() {
  54. // Handle back button press inside WebView
  55. if (webView.canGoBack()) {
  56. webView.goBack();
  57. } else {
  58. super.onBackPressed();
  59. }
  60. }
  61. }

huangapple
  • 本文由 发表于 2023年6月1日 15:20:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76379534.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定