所以我有一个api,可以使用JWT创建、登录等等。现在我的Login类太广泛了,对我喜欢的东西有太多的责任。这就是了;
[HttpPost("login")]
public async Task<IActionResult> Login(UserForLoginDto user)
{
var userFromRepo = await _qrepo.Login(user.Username, user.Password);
//IF no user found in db
if (userFromRepo == null)
//Return unauth so if user have wrong login creds, we're not specifying if it's password or username
return Unauthorized();
//Token creation
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, userFromRepo.Id.ToString()),
new Claim(ClaimTypes.Name, userFromRepo.Username)
};
// Hashed token Key
// The token is unique and very secret - if you have the token you are able to create tokens that are verifyable for our backend
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config.GetSection("AppSettings:Token").Value));
// Signing credentials
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
// Security Token DEscripter
var tokenDescriptor = new SecurityTokenDescriptor
{
// our claims
Subject = new ClaimsIdentity(claims),
// Expiry date - 1 day from create
Expires = DateTime.Now.AddDays(1),
SigningCredentials = creds
};
// Token handler
var tokenHandler = new JwtSecurityTokenHandler();
// Actual token
var token = tokenHandler.CreateToken(tokenDescriptor);
// Return actual token
return Ok(new
{
token = tokenHandler.WriteToken(token)
});
}
我希望我的令牌创建从我的控制器方法中分离出来,但我不完全确定什么是最好的方法,那么这应该属于哪里呢?这是我的文件夹结构:
我觉得它不属于我的任何一个文件夹,但可能在helpers中,idk?这方面的标准方法是什么?
发布于 2019-06-05 00:59:19
你能把所有令牌生成的东西放在一个单独的服务类中吗?然后使用DI注入服务。还可以给它一个接口,这样你就可以更容易地测试它:
public interface IJwtTokenGenerator
{
string GenerateToken(User user);
}
public class JwtTokenGenerator : IJwtTokenGenerator
{
private readonly IConfiguration _config;
public JwtTokenGenerator(IConfiguration config)
{
_config = config;
}
//obviously, change User to whatever your user class name is
public string GenerateToken(User user)
{
//Token creation
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.Username)
};
// Hashed token Key
// The token is unique and very secret - if you have the token you are able to create tokens that are verifyable for our backend
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config.GetSection("AppSettings:Token").Value));
// Signing credentials
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
// Security Token DEscripter
var tokenDescriptor = new SecurityTokenDescriptor
{
// our claims
Subject = new ClaimsIdentity(claims),
// Expiry date - 1 day from create
Expires = DateTime.Now.AddDays(1),
SigningCredentials = creds
};
// Token handler
var tokenHandler = new JwtSecurityTokenHandler();
// Actual token
var securityToken = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(securityToken);
}
}
则您的登录操作可能如下所示:
[HttpPost("login")]
public async Task<IActionResult> Login(UserForLoginDto user)
{
var userFromRepo = await _qrepo.Login(user.Username, user.Password);
//IF no user found in db
if (userFromRepo == null)
//Return unauth so if user have wrong login creds, we're not specifying if it's password or username
return Unauthorized();
//Injected ITokenGenerator (note the interface)
var token = _tokenGenerator.GenerateToken(userFromRepo);
// Return actual token
return Ok(new
{
token
});
}
至于放置这个类和接口的文件夹(应该是两个单独的文件),这主要取决于什么对您或您的团队有意义。也许另一个文件夹叫做"Services",也许是"Authentication",也许是"Authentication/Services“。“Helper”通常用于静态类,但我想您可以将其放入其中。
https://stackoverflow.com/questions/56452919
复制