You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 00:27:03