基于Web API与AppShell的Xamarin Forms登录登出及Cookie管理问询
1. 捕获并存储API返回的Cookie
首先需要修改API请求逻辑,用CookieContainer捕获登录接口返回的Cookie,并通过静态类统一管理:
步骤1:创建身份验证管理类
public static class AuthManager { // 全局Cookie容器,存储登录后的会话Cookie public static CookieContainer CookieContainer { get; } = new CookieContainer(); // 判断是否已登录 public static bool IsAuthenticated => CookieContainer.Count > 0 || !string.IsNullOrEmpty(Preferences.Get("userId", string.Empty)); // 清除所有身份验证数据 public static void ClearAuthData() { CookieContainer.Clear(); Preferences.Remove("userId"); // 若存储了其他用户信息,一并移除 } }
步骤2:修改API请求方法以捕获Cookie
调整你的SendPostRequestFromBody方法,使用HttpClientHandler绑定全局Cookie容器:
public static ApiResult SendPostRequestFromBody(string serviceUrl, List<ServiceParameterObject> paramList) { using (var handler = new HttpClientHandler { CookieContainer = AuthManager.CookieContainer }) using (var client = new HttpClient(handler)) { var json = JsonConvert.SerializeObject(paramList); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = client.PostAsync(serviceUrl, content).Result; response.EnsureSuccessStatusCode(); var responseString = response.Content.ReadAsStringAsync().Result; return JsonConvert.DeserializeObject<ApiResult>(responseString); } }
2. 后续API请求携带Cookie
所有需要身份验证的API请求,都要复用AuthManager.CookieContainer,确保会话保持:
public static ApiResult SendAuthenticatedGetRequest(string serviceUrl) { using (var handler = new HttpClientHandler { CookieContainer = AuthManager.CookieContainer }) using (var client = new HttpClient(handler)) { var response = client.GetAsync(serviceUrl).Result; response.EnsureSuccessStatusCode(); var responseString = response.Content.ReadAsStringAsync().Result; return JsonConvert.DeserializeObject<ApiResult>(responseString); } }
3. 登出逻辑实现
在需要触发登出的位置(如侧边栏菜单按钮)添加以下代码:
private async Task Logout() { // 清除Cookie和本地存储的用户数据 AuthManager.ClearAuthData(); // 通过AppShell路由跳转回登录页 await Shell.Current.GoToAsync($"//{nameof(LoginPage)}"); }
4. AppShell路由与启动导航控制
定义路由(AppShell.xaml)
<Shell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:YourAppNamespace" x:Class="YourAppNamespace.AppShell"> <!-- 登录页路由 --> <ShellContent Route="LoginPage" ContentTemplate="{DataTemplate local:LoginPage}" /> <!-- 首页及其他授权页面 --> <FlyoutItem Title="首页" Icon="home_icon.png"> <ShellContent Route="HomePage" ContentTemplate="{DataTemplate local:HomePage}" /> </FlyoutItem> </Shell>
启动时判断登录状态(App.xaml.cs)
protected override async void OnStart() { if (AuthManager.IsAuthenticated) { await Shell.Current.GoToAsync($"//{nameof(HomePage)}"); } else { await Shell.Current.GoToAsync($"//{nameof(LoginPage)}"); } }
5. 优化登录代码
更新你的登录逻辑,确保Cookie自动被捕获:
if (Connectivity.NetworkAccess == NetworkAccess.Internet) { var userName = tbName.Text; var password = tbPassword.Text; var serviceUrl = "你的登录API地址"; var paramList = new List<ServiceParameterObject>(); paramList.Add(new ServiceParameterObject("_userCode", userName)); paramList.Add(new ServiceParameterObject("_userPassword", password)); var apiResult = ApiResult.SendPostRequestFromBody(serviceUrl, paramList); if (apiResult.Status) { var user = JsonConvert.DeserializeObject<User>(apiResult.Message); Preferences.Set("userId", user.Id.ToString()); await Shell.Current.GoToAsync($"//{nameof(HomePage)}"); } else { await DisplayAlert("提示", "用户名或密码错误,请重试。", "确定"); } } else { await DisplayAlert("提示", "无网络连接,请检查后重试。", "确定"); }
安全提示
- 若需要持久化Cookie(如记住登录),不要直接用
Preferences存储敏感内容,建议使用Xamarin.Essentials.SecureStorage加密存储。 - 登出时务必清除所有相关数据,避免残留会话信息导致安全风险。
内容的提问来源于stack exchange,提问作者Arslan
相关产品推荐
相关产品推荐

