我对.NET Core相当陌生,但是我试图编写尽可能遵循SOLID主体的代码。
在我的网站中注册的用户可能会决定使用使用同一电子邮件的Facebook帐户登录;这会引发错误,因为我的用户表中的电子邮件字段是唯一的。
我对此的解决方法是像这样创建某种关联表Users_Facebook ...
在我要注册用户的控制器中;要获取userId,我已经实现了一项服务(A.检查user_facebook表中是否存在现有用户,或(B.基于电子邮件将Facebook userId与现有用户相关联。
[Route("api/Users")]
[HttpPost]
public async Task<int> RegisterUser()
{
var userId = await userService.GetUserIdAsync(User);
var email = User.Claims.First(e => e.Type == "emails").Value;
var user = await _unitOfWork.Users.GetUserByIdAsync(userId);
// Check contacts to see if one needs to be associated with a user
var contact = await _unitOfWork.Contacts.GetContactByEmail(email);
...
服务摘要:
public async Task<string> GetUserIdAsync(ClaimsPrincipal authedUser)
{
var userId = authedUser.Claims.First(e => e.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
var email = authedUser.Claims.First(e => e.Type == "emails").Value;
var identityProvider = authedUser.HasClaim(e => e.Type == "http://schemas.microsoft.com/identity/claims/identityprovider") ?
authedUser.Claims.First(e => e.Type == "http://schemas.microsoft.com/identity/claims/identityprovider").Value : null;
...
我的问题是,这有什么问题吗?我可以将ClaimsPrincipal传递给我的服务吗?还是我打破了某种最佳实践?如果我完全不在家,有人可以建议做这种事情的更好方法吗?
预先感谢
答案 0 :(得分:1)
我个人不会将ClaimsPrincipal传递给方法。而是将IHttpContextAccessor传递到服务的构造函数中。这样,可以通过以下方法将其注册到DI容器中:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddHttpContextAccessor();
}
然后在服务类中像这样注入IHttpContextAccessor
:
public class MyClass(IHttpContextAccessor context)
{
}
这意味着您可以从类中访问当前上下文,而不必通过方法传递。
要访问当前登录的用户,只需像这样访问它:
var username = Context.User.Identity.Name;