如何在 .NET MAUI 应用中实现 Bearer Token 认证

发布:2024-09-09 16:59 阅读:22 点赞:2

一、概述

Bearer Token身份验证是一种现代的身份验证方式,常用于确保API的安全访问。在.NET MAUI应用中,您可以通过用户登录,获取Bearer Token,并使用该Token从API中获取受保护的数据。在本指南中,我们将详细介绍如何在.NET MAUI应用中实现这一过程,包括UI设计、C#处理用户认证和数据获取、以及如何通过Bearer Token实现安全的API调用。

二、UI界面设计(MainPage.xaml)

首先,我们需要为用户提供一个简单的登录界面,用于输入电子邮件和密码。以下是实现该界面的XAML代码。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Mauitemp.PageThree"
             Title="PageThree">

    <VerticalStackLayout Spacing="20">
        <!-- 标题文字 -->
        <Label
            Text="欢迎使用Bearer Token身份验证"
            VerticalOptions="Center"
            HorizontalOptions="Center"
            FontSize="24"
            FontAttributes="Bold"/>

        <Label/>
        
        <!-- 输入电子邮件 -->
        <Entry x:Name="Email" Placeholder="电子邮件" HorizontalOptions="Center" WidthRequest="250" />
        
        <!-- 输入密码 -->
        <Entry x:Name="Pass" Placeholder="密码" HorizontalOptions="Center" WidthRequest="250" IsPassword="True" />
        
        <!-- 提交按钮 -->
        <Button Text="获取数据" BackgroundColor="White" WidthRequest="250" Clicked="Button_Clicked"/>
        
        <Label/>
        
        <!-- 显示日期 -->
        <HorizontalStackLayout Spacing="20" HorizontalOptions="Center">
            <Label Text="日期:" TextColor="White" FontSize="24" />
            <Label x:Name="Date" Text="" TextColor="Red" FontSize="24" />
        </HorizontalStackLayout>

        <Label/>

        <!-- 显示温度(华氏) -->
        <HorizontalStackLayout Spacing="20" HorizontalOptions="Center">
            <Label Text="温度(°F):" TextColor="White" FontSize="24" />
            <Label x:Name="TempF" Text="" TextColor="Red" FontSize="24" />
        </HorizontalStackLayout>

        <Label/>

        <!-- 显示温度(摄氏) -->
        <HorizontalStackLayout Spacing="20" HorizontalOptions="Center">
            <Label Text="温度(°C):" TextColor="White" FontSize="24" />
            <Label x:Name="TempC" Text="" TextColor="Red" FontSize="24" />
        </HorizontalStackLayout>

        <Label/>

        <!-- 显示天气摘要 -->
        <HorizontalStackLayout Spacing="20">
            <Label Text="摘要:" TextColor="White" FontSize="24" />
            <Label x:Name="Summary" Text="" TextColor="Red" FontSize="24" />
        </HorizontalStackLayout>
    </VerticalStackLayout>
</ContentPage>

2.1 界面设计解析

  • Entry 控件用于输入用户的电子邮件和密码信息。
  • Button 控件用于提交认证请求,并在用户点击时触发数据获取。
  • Label 控件展示了从API中获取的数据,包括日期、温度(华氏度和摄氏度)、以及天气摘要。

三、处理身份验证与数据获取(MainPage.cs)

用户点击按钮后,应用将发送POST请求,提交用户的凭证进行身份验证,并获取Bearer Token。该Token会用于访问受保护的API并获取天气数据。以下是相应的C#代码。

using Mauitemp.Model;
using System.Diagnostics;
using System.Text.Json;

namespace Mauitemp
{
    public partial class PageThree : ContentPage
    {
        private readonly RestService restService;

        public PageThree()
        {
            InitializeComponent();
        }

        private async void Button_Clicked(object sender, EventArgs e)
        {
            // 构建用户凭证模型
            BModel model = new()
            {
                email = Email.Text,
                password = Pass.Text
            };

            // 登录和天气数据的API地址
            string loginUrl = "https://localhost:7111/login";
            string weatherUrl = "https://localhost:7111/WeatherForecast";

            // 发送POST请求进行登录
            (int statuscode, string content) = await RestService.HTTPCall2(loginUrl, "POST", model, false);

            if (statuscode == 200)
            {
                // 解析响应获取Token
                BModel User = BModel.GetInstance;
                BModel UserData = JsonSerializer.Deserialize<BModel>(content);

                if (UserData != null)
                {
                    User.accessToken = UserData.accessToken;
                }

                // 如果成功获取Token,发送请求获取天气数据
                if (!string.IsNullOrEmpty(User.accessToken))
                {
                    (int statuscode1, string content1) = await RestService.HTTPCall2(weatherUrl, "GET"nulltrue);

                    if (statuscode1 == 200)
                    {
                        // 解析并展示天气数据
                        var weatherData = JsonSerializer.Deserialize<List<BModel>>(content1);
                        if (weatherData != null)
                        {
                            Date.Text = weatherData[0].date.ToString();
                            TempF.Text = weatherData[0].temperatureF.ToString();
                            TempC.Text = weatherData[0].temperatureC.ToString();
                            Summary.Text = weatherData[0].summary;
                        }
                    }
                    else
                    {
                        await DisplayAlert("错误""无法获取天气数据""OK");
                    }
                }
                else
                {
                    await DisplayAlert("错误""Token未获取到""OK");
                }
            }
            else
            {
                await DisplayAlert("错误""无效的凭证""OK");
            }
        }
    }
}

3.1 代码说明

  • 凭证模型:将用户输入的电子邮件和密码打包为模型对象发送到登录API。
  • POST请求:通过RestService.HTTPCall2方法发送POST请求进行身份验证。
  • Bearer Token:如果认证成功,从响应中提取Bearer Token,并将其存储在用户模型中。
  • 天气数据获取:使用获取的Bearer Token访问天气数据API,并展示API返回的天气信息。

四、RestService类(RestService.cs)

RestService类负责处理HTTP请求,并在需要时为请求添加Bearer Token。下面是实现的代码。

using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Mauitemp
{
    public class RestService
    {
        private static readonly HttpClient _client = new HttpClient();
        private static readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = true
        };

        // 用于处理HTTP请求
        public static async Task<(int ResultValue, string ResponseContent)> HTTPCall2(string url, string method, object data, bool Auth)
        {
            HttpResponseMessage response;
            string responseContent = string.Empty;

            // 如果需要进行Bearer Token认证
            if (Auth)
            {
                BModel UserProfile = BModel.GetInstance;
                string AuthToken = UserProfile.accessToken;
                _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthToken);
            }

            try
            {
                // 根据HTTP方法发送请求
                if (method.ToUpper() == "GET")
                {
                    response = await _client.GetAsync(url);
                }
                else if (method.ToUpper() == "POST")
                {
                    var jsonData = JsonSerializer.Serialize(data, _serializerOptions);
                    var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
                    response = await _client.PostAsync(url, content);
                }
                else
                {
                    throw new ArgumentException("HTTP方法不支持,请使用'GET'或'POST'");
                }

                responseContent = await response.Content.ReadAsStringAsync();
                return ((int)response.StatusCode, responseContent);
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"\t错误: {ex.Message}");
                return (-1$"错误: {ex.Message}");
            }
        }
    }
}

4.1 RestService的工作机制

  • HTTP请求:该类封装了GET和POST请求的发送逻辑,同时为需要认证的请求添加了Bearer Token。
  • 异常处理:处理请求过程中出现的任何异常,并将错误信息返回。

五、总结

本文介绍了如何在.NET MAUI应用中使用Bearer Token进行身份验证。通过创建用户登录界面,发送POST请求获取Bearer Token,使用该Token访问受保护的API数据,我们能够安全地在应用中实现用户认证和数据获取。