我有一个使用 Google 进行身份验证的 Blazor Web Assembly 应用程序。身份验证工作完美,即它登录后我得到身份的名称并能够在网站上显示它。 OnSuccessfulLogin 事件被调用,但我无法收到登录用户的电子邮件地址(帐户持有人的姓名来自 user.Identity.Name)。
连接到 Google 的 API 代码也已经正确配置,我可以看到 身份验证范围被返回为:
openid 轮廓 电子邮件
有没有办法使用 Blazor 从 Google 登录接收电子邮件地址?
下面是处理不同事件的 authentication.razor 页面。
@page "/authentication/{action}"
@using Core.Models.Entity
@using Core.Models.Requests.Query
@using Core.Models.Responses.Query
@using Core.Extensions
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Types
@using Microsoft.AspNetCore.Components.Authorization
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject IJSRuntime js
@inject Microsoft.Extensions.Configuration.IConfiguration config
@inject StateContainer stateContainer
@inject HttpClient http
@inject NavigationManager navigator
<RemoteAuthenticatorView Action="@Action" OnLogInSucceeded="OnSuccessfulLogin">
<LogOutFailed />
<UserProfile>
<h1>Please Select Your Institution</h1>
<div class="row row-cols-2">
<div class="col">
@if (tenants != null && tenants.Count > 0)
{
<MudSelect Label="Institution" @bind-Value="SelectedTenant">
@foreach (Tenant item in tenants)
{
<MudSelectItem Value="@item">@item.Name, @item.StreetAddress</MudSelectItem>
}
</MudSelect>
}
</div>
</div>
<div class="row">
<div class="col mt-2">
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="OnNext">Next</MudButton>
</div>
</div>
</UserProfile>
<CompletingLoggingIn>
<h3>Completing logging in...</h3>
</CompletingLoggingIn>
</RemoteAuthenticatorView>
@code {
[Parameter]
public string Action { get; set; }
[CascadingParameter]
public Task<AuthenticationState> AuthState { get; set; }
private QueryTenantsResponse tenants;
public Tenant SelectedTenant { get; set; }
public ApplicationAuthenticationState AuthenticationState { get; set; } = new ApplicationAuthenticationState();
protected override async Task OnInitializedAsync()
{
tenants = new QueryTenantsResponse();
QueryCollectionRequest request = new QueryCollectionRequest
{
EntityType = Core.Constants.EntityTypeEnum.Tenant,
UserId = Guid.Empty,
TenantId = Guid.Empty,
Token = Guid.Empty,
Paging = new Paging
{
ItemsPerPage = 1000,
Page = 0
}
};
string resource = $"{config["Api:BaseAddress"]}/Institutions";
tenants = await request.HttpGet<QueryCollectionRequest, QueryTenantsResponse>(http, resource);
if (RemoteAuthenticationActions.IsAction(RemoteAuthenticationActions.LogIn, Action) || RemoteAuthenticationActions.IsAction(RemoteAuthenticationActions.LogOut, Action))
{
AuthenticationState.Id = Guid.NewGuid().ToString();
await js.InvokeVoidAsync("sessionStorage.setItem", AuthenticationState.Id, stateContainer.PrepareForLocalStorage());
}
}
private void OnNext()
{
stateContainer.Tenant = SelectedTenant;
navigator.NavigateTo("/authentication/login");
// 1. sign in with google to get user email
// 2. once email received
// 3. sign in user to get token
}
private void SignInUser()
{
}
private async Task OnSuccessfulLogin()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
AuthenticationState state = await AuthState;
@* ClaimsPrincipal user = state.User; *@
foreach (var claim in user.Claims)
{
System.Console.WriteLine($"claim: issuer={claim.Issuer}, original issuer={claim.OriginalIssuer}, claim value={claim.Value}, value type={claim.ValueType}");
System.Console.WriteLine("claim properties:\n");
foreach (var property in claim.Properties)
{
System.Console.WriteLine($"- key={property.Key}, value={property.Value}");
}
}
System.Console.WriteLine($"user identity name: {user.Identity.Name}");
System.Console.WriteLine($"is authenticated: {user.Identity.IsAuthenticated}");
}
private async Task RestoreState(ApplicationAuthenticationState state)
{
if (state.Id != null)
{
string locallyStoredState = await js.InvokeAsync<string>("sessionStorage.getItem", state.Id);
if (!string.IsNullOrWhiteSpace(locallyStoredState))
{
stateContainer.RestoreState(locallyStoredState);
await js.InvokeVoidAsync("sessionStorage.removeItem", state.Id);
}
}
}
}