[英]How to customize Identity controller for React SPA in ASP.NET Core?
I followed official tutorial for identity with SPA from microsoft.我遵循了微软的 SPA 身份官方教程。 However right now I need more data in my user table.但是现在我的用户表中需要更多数据。 So I followed customise identity tutorial but that is for razor pages.所以我遵循了自定义身份教程,但那是针对剃刀页面的。 Right now when I open my scaffolded react app, I can't see any controller to customise.现在,当我打开脚手架的 React 应用程序时,我看不到任何要自定义的控制器。 I can add new data from the model, however how do I customise the controller for user register in react SPA?我可以从模型中添加新数据,但是如何在 react SPA 中为用户注册自定义控制器?
You need customize existing interface of Identity:您需要自定义 Identity 的现有界面:
For example:例如:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using shadow.Models;
using shadow.Shared;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace shadow.Services
{
public interface IUserService
{
Task<UserManagerResponse> RegisterUserAsync(RegisterViewModel model);
Task<UserManagerResponse> LoginUserAsync(LoginViewModel model);
Task<UserManagerResponse> LogoutUserAsync(LoginViewModel model);
Task<UserManagerResponse> ConfirmEmailAsync(string userId, string token);
Task<UserManagerResponse> ForgetPasswordAsync(string email);
Task<UserManagerResponse> ResetPasswordAsync(ResetPasswordViewModel model);
}
public class UserService : IUserService
{
private UserManager<ApplicationUser> _userManger;
private IConfiguration _configuration;
private IMailService _mailService;
public UserService(UserManager<ApplicationUser> userManager, IConfiguration configuration, IMailService mailService)
{
_userManger = userManager;
_configuration = configuration;
_mailService = mailService;
}
/// <summary>
/// Đăng ký.
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<UserManagerResponse> RegisterUserAsync(RegisterViewModel model)
{
if (model == null)
{
throw new NullReferenceException("Reigster Model is null");
}
if (model.Password != model.ConfirmPassword)
{
return new UserManagerResponse
{
Message = "Confirm password doesn't match the password",
IsSuccess = false,
};
}
var identityUser = new ApplicationUser
{
Email = model.Email,
UserName = model.Email,
About = model.About,
SecondMobile = model.SecondMobile,
Fullname = model.Fullname,
AliasName = model.AliasName,
Created = DateTime.Now,
Modified = DateTime.Now
};
var result = await _userManger.CreateAsync(identityUser, model.Password);
if (result.Succeeded)
{
var confirmEmailToken = await _userManger.GenerateEmailConfirmationTokenAsync(identityUser);
var encodedEmailToken = Encoding.UTF8.GetBytes(confirmEmailToken);
var validEmailToken = WebEncoders.Base64UrlEncode(encodedEmailToken);
string url = $"{_configuration["AppUrl"]}/api/auth/ConfirmEmail?userId={identityUser.Id}&token={validEmailToken}";
await _mailService.SendEmailAsync(identityUser.Email, "Confirm your email", $"<h1>Welcome to Trustee app</h1>" +
$"<p>Please confirm your email by <a href='{url}'>clicking here</a></p>");
return new UserManagerResponse
{
Message = "User created successfully!",
IsSuccess = true,
};
}
return new UserManagerResponse
{
Message = "User did not create",
IsSuccess = false,
Errors = result.Errors.Select(e => e.Description)
};
}
/// <summary>
/// Đăng nhập.
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<UserManagerResponse> LoginUserAsync(LoginViewModel model)
{
var user = await _userManger.FindByEmailAsync(model.Email);
if (user == null)
{
return new UserManagerResponse
{
Message = "There is no user with that Email address",
IsSuccess = false,
};
}
var result = await _userManger.CheckPasswordAsync(user, model.Password);
if (!result)
{
return new UserManagerResponse
{
Message = "Invalid password",
IsSuccess = false,
};
}
var claims = new[]
{
new Claim("Email", model.Email),
new Claim(ClaimTypes.NameIdentifier, user.Id),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["AuthSettings:Key"]));
var token = new JwtSecurityToken(
issuer: _configuration["AuthSettings:Issuer"],
audience: _configuration["AuthSettings:Audience"],
claims: claims,
expires: DateTime.Now.AddDays(30),
signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256));
string tokenAsString = new JwtSecurityTokenHandler().WriteToken(token);
return new UserManagerResponse
{
Message = tokenAsString,
IsSuccess = true,
ExpireDate = token.ValidTo
};
}
// Đăng xuất.
public async Task<UserManagerResponse> LogoutUserAsync(LoginViewModel model)
{
var user = await _userManger.FindByEmailAsync(model.Email);
if (user == null)
{
return new UserManagerResponse
{
Message = "There is no user with that Email address",
IsSuccess = false,
};
}
var result = await _userManger.CheckPasswordAsync(user, model.Password);
if (!result)
{
return new UserManagerResponse
{
Message = "Invalid password",
IsSuccess = false,
};
}
var claims = new[]
{
new Claim("Email", model.Email),
new Claim(ClaimTypes.NameIdentifier, user.Id),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["AuthSettings:Key"]));
var token = new JwtSecurityToken(
issuer: _configuration["AuthSettings:Issuer"],
audience: _configuration["AuthSettings:Audience"],
claims: claims,
expires: DateTime.Now.AddDays(30),
signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256));
string tokenAsString = new JwtSecurityTokenHandler().WriteToken(token);
return new UserManagerResponse
{
Message = tokenAsString,
IsSuccess = true,
ExpireDate = token.ValidTo
};
}
public async Task<UserManagerResponse> ConfirmEmailAsync(string userId, string token)
{
var user = await _userManger.FindByIdAsync(userId);
if (user == null)
{
return new UserManagerResponse { IsSuccess = false, Message = "User not found" };
}
var decodedToken = WebEncoders.Base64UrlDecode(token);
string normalToken = Encoding.UTF8.GetString(decodedToken);
var result = await _userManger.ConfirmEmailAsync(user, normalToken);
if (result.Succeeded)
{
return new UserManagerResponse { Message = "Email confirmed successfully!", IsSuccess = true };
}
return new UserManagerResponse
{
IsSuccess = false,
Message = "Email did not confirm",
Errors = result.Errors.Select(e => e.Description)
};
}
public async Task<UserManagerResponse> ForgetPasswordAsync(string email)
{
var user = await _userManger.FindByEmailAsync(email);
if (user == null)
{
return new UserManagerResponse { IsSuccess = false, Message = "No user associated with email", };
}
var token = await _userManger.GeneratePasswordResetTokenAsync(user);
var encodedToken = Encoding.UTF8.GetBytes(token);
var validToken = WebEncoders.Base64UrlEncode(encodedToken);
string url = $"{_configuration["AppUrl"]}/ResetPassword?email={email}&token={validToken}";
await _mailService.SendEmailAsync(email, "Reset Password", "<h1>Follow the instructions to reset your password</h1>" +
$"<p>To reset your password <a href='{url}'>Click here</a></p>");
return new UserManagerResponse
{
IsSuccess = true,
Message = "Reset password URL has been sent to the email successfully!"
};
}
public async Task<UserManagerResponse> ResetPasswordAsync(ResetPasswordViewModel model)
{
var user = await _userManger.FindByEmailAsync(model.Email);
if (user == null)
{
return new UserManagerResponse { IsSuccess = false, Message = "No user associated with email", };
}
if (model.NewPassword != model.ConfirmPassword)
{
return new UserManagerResponse { IsSuccess = false, Message = "Password doesn't match its confirmation", };
}
var decodedToken = WebEncoders.Base64UrlDecode(model.Token);
string normalToken = Encoding.UTF8.GetString(decodedToken);
var result = await _userManger.ResetPasswordAsync(user, normalToken, model.NewPassword);
if (result.Succeeded)
{
return new UserManagerResponse { Message = "Password has been reset successfully!", IsSuccess = true };
}
return new UserManagerResponse
{
Message = "Something went wrong",
IsSuccess = false,
Errors = result.Errors.Select(e => e.Description)
};
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.