Compare commits
5 Commits
fec25072c4
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| fc8d59ae12 | |||
| a74065f768 | |||
| 8838fcd65c | |||
| 803a9f86e1 | |||
| b3182b3ae7 |
40
App.Services/AuthService/AuthService.cs
Normal file
40
App.Services/AuthService/AuthService.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
|
using Sandbox.Models.ViewModels;
|
||||||
|
|
||||||
|
namespace Sandbox.App.Services.AuthService;
|
||||||
|
|
||||||
|
public class AuthService : IAuthService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _http;
|
||||||
|
//private readonly AuthenticationStateProvider _authenticationStateProvider;
|
||||||
|
|
||||||
|
// public AuthService(HttpClient httpClient, AuthenticationStateProvider authenticationStateProvider)
|
||||||
|
public AuthService(HttpClient httpClient)
|
||||||
|
{
|
||||||
|
_http = httpClient;
|
||||||
|
//_authenticationStateProvider = authenticationStateProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<int>> Register(UserRegister request)
|
||||||
|
{
|
||||||
|
var result = await _http.PostAsJsonAsync("api/auth/register", request);
|
||||||
|
return await result.Content.ReadFromJsonAsync<ServiceResponse<int>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public async Task<ServiceResponse<string>> Login(UserLogin request)
|
||||||
|
// {
|
||||||
|
// var result = await _http.PostAsJsonAsync("api/auth/login", request);
|
||||||
|
// return await result.Content.ReadFromJsonAsync<ServiceResponse<string>>();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public async Task<ServiceResponse<bool>> ChangePassword(UserChangePassword request)
|
||||||
|
// {
|
||||||
|
// var result = await _http.PostAsJsonAsync("api/auth/change-password", request.Password);
|
||||||
|
// return await result.Content.ReadFromJsonAsync<ServiceResponse<bool>>();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public async Task<bool> IsUserAuthenticated()
|
||||||
|
// {
|
||||||
|
// return (await _authenticationStateProvider.GetAuthenticationStateAsync()).User.Identity.IsAuthenticated;
|
||||||
|
// }
|
||||||
|
}
|
||||||
11
App.Services/AuthService/IAuthService.cs
Normal file
11
App.Services/AuthService/IAuthService.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Sandbox.Models.ViewModels;
|
||||||
|
|
||||||
|
namespace Sandbox.App.Services.AuthService;
|
||||||
|
|
||||||
|
public interface IAuthService
|
||||||
|
{
|
||||||
|
Task<ServiceResponse<int>> Register(UserRegister request);
|
||||||
|
// Task<ServiceResponse<string>> Login(UserLogin request);
|
||||||
|
// Task<ServiceResponse<bool>> ChangePassword(UserChangePassword request);
|
||||||
|
// Task<bool> IsUserAuthenticated();
|
||||||
|
}
|
||||||
@@ -1,38 +1,41 @@
|
|||||||
@page "/register"
|
@page "/register"
|
||||||
@using Sandbox.Models.ViewModels
|
@using Sandbox.Models.ViewModels
|
||||||
@using Sandbox.Services.AuthService
|
|
||||||
|
|
||||||
|
@inject Sandbox.App.Services.AuthService.IAuthService AuthService
|
||||||
@* @inject AuthenticationStateProvider AuthenticationStateProvider *@
|
@* @inject AuthenticationStateProvider AuthenticationStateProvider *@
|
||||||
@* @inject NavigationManager NavigationManager *@
|
@* @inject NavigationManager NavigationManager *@
|
||||||
@inject IAuthService AuthService
|
|
||||||
|
|
||||||
<title>Register</title>
|
<title>Register</title>
|
||||||
|
|
||||||
<EditForm Model="user" OnValidSubmit="HandleRegistration">
|
<EditForm Model="user" OnValidSubmit="HandleRegistration" OnInvalidSubmit="HandleInvalidSubmit" FormName="registerForm">
|
||||||
<DataAnnotationsValidator/>
|
<DataAnnotationsValidator/>
|
||||||
<div class="d-flex justify-content-center align-items-center">
|
<div class="d-flex justify-content-center align-items-center">
|
||||||
<div class="col-md-4 p-5 shadow-sm border rounded-3">
|
<div class="col-md-4 p-5 shadow-sm border rounded-3">
|
||||||
<h2 class="text-center mb-4 text-primary">Register Form</h2>
|
<h2 class="text-center mb-4 text-primary">Register Form</h2>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="email" class="form-label">Email address</label>
|
<label for="email" class="form-label">Email address</label>
|
||||||
<InputText type="email" @bind-Value="user.Email" class="form-control border border-primary" id="email" aria-describedby="email"/>
|
<InputText type="email" @bind-Value="user.Email" class="form-control border border-primary" id="email"
|
||||||
|
aria-describedby="email"/>
|
||||||
<ValidationMessage For="@(() => user.Email)"/>
|
<ValidationMessage For="@(() => user.Email)"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="password" class="form-label">Password</label>
|
<label for="password" class="form-label">Password</label>
|
||||||
<InputText type="password" @bind-Value="user.Password" class="form-control border border-primary" id="password" aria-describedby="password"/>
|
<InputText type="password" @bind-Value="user.Password" class="form-control border border-primary"
|
||||||
|
id="password" aria-describedby="password"/>
|
||||||
<ValidationMessage For="@(() => user.Password)"/>
|
<ValidationMessage For="@(() => user.Password)"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="confirmPassword" class="form-label">Confirm password</label>
|
<label for="confirmPassword" class="form-label">Confirm password</label>
|
||||||
<InputText type="password" @bind-Value="user.ConfirmPassword" class="form-control border border-primary" id="confirmPassword" aria-describedby="confirmPassword"/>
|
<InputText type="password" @bind-Value="user.ConfirmPassword" class="form-control border border-primary"
|
||||||
|
id="confirmPassword" aria-describedby="confirmPassword"/>
|
||||||
<ValidationMessage For="@(() => user.ConfirmPassword)"/>
|
<ValidationMessage For="@(() => user.ConfirmPassword)"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-grid">
|
<div class="d-grid">
|
||||||
<button class="btn btn-primary" type="submit">Register</button>
|
<button class="btn btn-primary" type="submit">Register</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3">
|
<div class="mt-3">
|
||||||
<p class="mb-0 text-center">You have an account? <a href="login" class="text-primary fw-bold">Sign In</a></p>
|
<p class="mb-0 text-center">You have an account? <a href="login" class="text-primary fw-bold">Sign
|
||||||
|
In</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -47,16 +50,29 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
UserRegister user = new();
|
[SupplyParameterFromForm] private UserRegister user { get; set; }
|
||||||
|
|
||||||
|
//HttpClient _http = new() { BaseAddress = new("https://localhost:7122") };
|
||||||
|
|
||||||
private string message = string.Empty;
|
private string message = string.Empty;
|
||||||
private string messageCssClass = string.Empty;
|
private string messageCssClass = string.Empty;
|
||||||
private string errorMessage = string.Empty;
|
private string errorMessage = string.Empty;
|
||||||
|
|
||||||
async void HandleRegistration()
|
protected override void OnInitialized() => user ??= new();
|
||||||
|
|
||||||
|
async Task HandleRegistration()
|
||||||
{
|
{
|
||||||
var result = await AuthService.Register(user.Email, user.Password);
|
// var response = await _http.PostAsJsonAsync("/api/register", user);
|
||||||
|
// var result = await response.Content.ReadFromJsonAsync<ServiceResponse<int>>();
|
||||||
|
var result = await AuthService.Register(user);
|
||||||
message = result.Message;
|
message = result.Message;
|
||||||
messageCssClass = result.Success ? "text-success" : "text-danger";
|
messageCssClass = result.Success ? "text-success" : "text-danger";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async Task HandleInvalidSubmit()
|
||||||
|
{
|
||||||
|
message = "Data annotations validation failed.";
|
||||||
|
messageCssClass = "text-danger";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
50
HttpClientSetupService.cs
Normal file
50
HttpClientSetupService.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using Microsoft.AspNetCore.Hosting.Server;
|
||||||
|
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||||
|
|
||||||
|
namespace Sandbox;
|
||||||
|
|
||||||
|
public class HttpClientSetupService(
|
||||||
|
HttpClient httpClient,
|
||||||
|
IServer server,
|
||||||
|
IHostApplicationLifetime applicationLifetime)
|
||||||
|
: BackgroundService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
|
||||||
|
private readonly IServer _server = server ?? throw new ArgumentNullException(nameof(server));
|
||||||
|
private readonly IHostApplicationLifetime _applicationLifetime = applicationLifetime ?? throw new ArgumentNullException(nameof(applicationLifetime));
|
||||||
|
|
||||||
|
protected override Task ExecuteAsync(CancellationToken stoppingToken)
|
||||||
|
{
|
||||||
|
var applicationStartedToken = _applicationLifetime.ApplicationStarted;
|
||||||
|
if (applicationStartedToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
ConfigureHttpClient();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
applicationStartedToken.Register(ConfigureHttpClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureHttpClient()
|
||||||
|
{
|
||||||
|
var serverAddresses = _server.Features.Get<IServerAddressesFeature>();
|
||||||
|
var address = serverAddresses.Addresses.FirstOrDefault();
|
||||||
|
if (address == null)
|
||||||
|
{
|
||||||
|
// Default ASP.NET Core Kestrel endpoint
|
||||||
|
address = "http://localhost:5000";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
address = address.Replace("*", "localhost", StringComparison.Ordinal);
|
||||||
|
address = address.Replace("+", "localhost", StringComparison.Ordinal);
|
||||||
|
address = address.Replace("[::]", "localhost", StringComparison.Ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
var baseUri = new Uri(address);
|
||||||
|
_httpClient.BaseAddress = baseUri;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
Program.cs
19
Program.cs
@@ -1,5 +1,9 @@
|
|||||||
|
using Sandbox;
|
||||||
using Sandbox.Components;
|
using Sandbox.Components;
|
||||||
|
using Sandbox.Models.ViewModels;
|
||||||
using Sandbox.Services.AuthService;
|
using Sandbox.Services.AuthService;
|
||||||
|
using ClientServices = Sandbox.App.Services;
|
||||||
|
using ServerServices = Sandbox.Services;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
@@ -7,8 +11,16 @@ var builder = WebApplication.CreateBuilder(args);
|
|||||||
builder.Services.AddRazorComponents()
|
builder.Services.AddRazorComponents()
|
||||||
.AddInteractiveServerComponents();
|
.AddInteractiveServerComponents();
|
||||||
|
|
||||||
|
// Blazor client services
|
||||||
|
builder.Services.AddScoped<ClientServices.AuthService.IAuthService, ClientServices.AuthService.AuthService>();
|
||||||
|
|
||||||
|
// Blazor server services
|
||||||
builder.Services.AddScoped<IAuthService, AuthService>();
|
builder.Services.AddScoped<IAuthService, AuthService>();
|
||||||
|
|
||||||
|
// Get server base address when application starts to properly configure HttpClient for client service to call server service
|
||||||
|
builder.Services.AddSingleton<HttpClient>();
|
||||||
|
builder.Services.AddSingleton<IHostedService, HttpClientSetupService>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
@@ -18,13 +30,18 @@ if (!app.Environment.IsDevelopment())
|
|||||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||||
app.UseHsts();
|
app.UseHsts();
|
||||||
}
|
}
|
||||||
|
|
||||||
app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
|
app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
app.UseAntiforgery();
|
app.UseAntiforgery();
|
||||||
|
|
||||||
|
// Blazor server routing
|
||||||
|
app.MapPost("/api/auth/register", async (UserRegister request, IAuthService authService) =>
|
||||||
|
await authService.Register(request));
|
||||||
|
|
||||||
app.MapStaticAssets();
|
app.MapStaticAssets();
|
||||||
app.MapRazorComponents<App>()
|
app.MapRazorComponents<App>()
|
||||||
.AddInteractiveServerRenderMode();
|
.AddInteractiveServerRenderMode();
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
@@ -4,12 +4,12 @@ namespace Sandbox.Services.AuthService;
|
|||||||
|
|
||||||
public class AuthService : IAuthService
|
public class AuthService : IAuthService
|
||||||
{
|
{
|
||||||
public async Task<ServiceResponse<int>> Register(string userName, string password)
|
public async Task<ServiceResponse<int>> Register(UserRegister userRegister)
|
||||||
{
|
{
|
||||||
return new ServiceResponse<int>
|
return new ServiceResponse<int>
|
||||||
{
|
{
|
||||||
Data = 1,
|
Data = 1,
|
||||||
Message = $"Got register request with user name {userName}",
|
Message = $"Got register request with e-mail {userRegister.Email}",
|
||||||
Success = true
|
Success = true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ namespace Sandbox.Services.AuthService;
|
|||||||
|
|
||||||
public interface IAuthService
|
public interface IAuthService
|
||||||
{
|
{
|
||||||
Task<ServiceResponse<int>> Register(string userName, string password);
|
Task<ServiceResponse<int>> Register(UserRegister userRegister);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user