如何让Blazor Server登录页的「记住我」在Android WebView稳定生效?
Android WebView加载Blazor Server应用时「记住我」功能不稳定的解决方案
问题背景
我开发的Blazor Server应用使用内置AuthenticationStateProvider服务,网页端「记住我」功能正常。但通过Android WebView加载该网站时,该功能仅约1%的概率能稳定存储登录凭据(表现为清除Chrome历史、应用缓存后仍保持登录,清除应用全部数据才会登出),其余情况每次打开应用都需重新登录。已启用JavaScript及第三方Cookie,问题仍未解决。
现有代码
MainActivity.java
import android.annotation.SuppressLint; import android.graphics.Bitmap; import android.view.View; import android.webkit.CookieManager; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.ProgressBar; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { private WebView webView; private ProgressBar progressBar; @SuppressLint("SetJavaScriptEnabled") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = findViewById(R.id.webview); progressBar = findViewById(R.id.progressBar); // Configure WebView settings WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); CookieManager.getInstance().setAcceptCookie(true); CookieManager.getInstance().acceptThirdPartyCookies(webView); // Set WebView clients webView.setWebViewClient(new WebViewClient() { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); progressBar.setVisibility(View.VISIBLE); webView.setVisibility(View.GONE); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); progressBar.setVisibility(View.GONE); webView.setVisibility(View.VISIBLE); } }); webView.setWebChromeClient(new WebChromeClient() { public void onProgressChanged(WebView view, int progress) { progressBar.setProgress(progress); } }); // Load the website webView.loadUrl("URL HERE"); } @Override public void onBackPressed() { // Handle back button press inside WebView if (webView.canGoBack()) { webView.goBack(); } else { super.onBackPressed(); } } }
AndroidManifest.xml 添加的权限
<uses-permission android:name="android.permission.INTERNET"/>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone" /> <ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_centerHorizontal="true" android:indeterminate="false" android:max="100" android:progress="0" android:visibility="gone" /> </RelativeLayout>
解决步骤
1. 完善Cookie持久化配置
WebView默认可能不会持久化Cookie,需显式配置并同步:
// 导入必要类 import android.os.Build; import android.webkit.CookieSyncManager; // 在onCreate中初始化WebView前添加 CookieManager cookieManager = CookieManager.getInstance(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { cookieManager.setAcceptThirdPartyCookies(webView, true); } else { cookieManager.setAcceptCookie(true); } // 允许文件协议Cookie cookieManager.setAcceptFileSchemeCookies(true); // 强制同步Cookie(适配不同Android版本) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { cookieManager.flush(); } else { CookieSyncManager.createInstance(this); CookieSyncManager.getInstance().sync(); }
2. 启用WebView本地存储支持
Blazor的「记住我」依赖持久化存储,需开启DOM、数据库及应用缓存:
WebSettings webSettings = webView.getSettings(); // 启用DOM存储API webSettings.setDomStorageEnabled(true); // 启用数据库存储 webSettings.setDatabaseEnabled(true); // 低版本Android需设置数据库路径 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { webSettings.setDatabasePath(getApplicationContext().getFilesDir().getPath() + "/databases"); } // 启用应用缓存并设置路径 webSettings.setAppCacheEnabled(true); webSettings.setAppCachePath(getApplicationContext().getCacheDir().getPath());
3. 处理生命周期中的Cookie同步
在Activity的onPause和onResume中同步Cookie,避免进程回收导致丢失:
@Override protected void onPause() { super.onPause(); // 同步Cookie if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { CookieManager.getInstance().flush(); } else { CookieSyncManager.getInstance().sync(); } webView.onPause(); } @Override protected void onResume() { super.onResume(); webView.onResume(); // 低版本重新同步Cookie if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { CookieSyncManager.getInstance().sync(); } }
4. 检查Blazor Server端Cookie配置
确保服务端「记住我」Cookie设置了正确的持久化属性:
// 在Program.cs或Startup.cs中配置 builder.Services.ConfigureApplicationCookie(options => { options.Cookie.HttpOnly = true; options.ExpireTimeSpan = TimeSpan.FromDays(30); // 设置有效期 options.LoginPath = "/Login"; options.SlidingExpiration = true; // 滑动过期,自动延长有效期 });
登录时需正确传递IsPersistent参数:
await HttpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties { IsPersistent = true, // 开启记住我 ExpiresUtc = DateTimeOffset.UtcNow.AddDays(30) });
5. 禁用WebView隐私模式
部分设备默认开启隐私模式会阻止Cookie持久化,需显式关闭:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { webSettings.setPrivacyPreferencesEnabled(false); }
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

