目前上面的控制器只实现了基本的逻辑,下面我们要创建签发token的服务,去完成具体的业务。第一步我们先创建对应的服务接口,命名为 IAuthenticateService
public interface IAuthenticateService
{
bool IsAuthenticated(LoginRequestDTO request, out string token);
}
接下来,实现接口
public class TokenAuthenticationService : IAuthenticateService
{
public bool IsAuthenticated(LoginRequestDTO request, out string token)
{
throw new NotImplementedException();
}
}
在 Startup 的 ConfigureServices 方法中注册服务
services.AddScoped<IAuthenticateService, TokenAuthenticationService>();
在Controller中注入IAuthenticateService服务,并完善action
public class AuthenticationController : ControllerBase
{
private readonly IAuthenticateService _authService;
public AuthenticationController(IAuthenticateService authService)
{
this._authService = authService;
}
[AllowAnonymous]
[HttpPost, Route("requestToken")]
public ActionResult RequestToken([FromBody] LoginRequestDTO request)
{
if (!ModelState.IsValid)
{
return BadRequest("Invalid Request");
}
string token;
if (_authService.IsAuthenticated(request, out token))
{
return Ok(token);
}
return BadRequest("Invalid Request");
}
}
正常情况,我们都会根据请求的用户和密码去验证用户是否合法,需要连接到数据库获取数据进行校验,我们这里为了方便,假设任何请求的用户都是合法的。
这里单独加个用户管理的服务,不在IAuthenticateService这个服务里面添加相应逻辑,主要遵循了 职责单一原则 。首先和上面一样,创建一个服务接口 IUserService
public interface IUserService
{
bool IsValid(LoginRequestDTO req);
}
实现 IUserService 接口
public class UserService : IUserService
{
//模拟测试,默认都是人为验证有效
public bool IsValid(LoginRequestDTO req)
{
return true;
}
}
同样注册到容器中
services.AddScoped<IUserService, UserService>();
接下来,就要完善TokenAuthenticationService签发token的逻辑,首先要注入IUserService 和 TokenManagement,然后实现具体的业务逻辑,这个token的生成还是使用的Jwt的类库提供的api,具体不详细描述。
特别注意下TokenManagement的注入是已IOptions的接口类型注入的,还记得在Startpup中吗?我们是通过配置项的方式注册TokenManagement类型的。
public class TokenAuthenticationService : IAuthenticateService
{
private readonly IUserService _userService;
private readonly TokenManagement _tokenManagement;
public TokenAuthenticationService(IUserService userService, IOptions<TokenManagement> tokenManagement)
{
_userService = userService;
_tokenManagement = tokenManagement.Value;
}
public bool IsAuthenticated(LoginRequestDTO request, out string token)
{
token = string.Empty;
if (!_userService.IsValid(request))
return false;
var claims = new[]
{
new Claim(ClaimTypes.Name,request.Username)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_tokenManagement.Secret));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var jwtToken = new JwtSecurityToken(_tokenManagement.Issuer, _tokenManagement.Audience, claims, expires: DateTime.Now.AddMinutes(_tokenManagement.AccessExpiration), signingCredentials: credentials);
token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
return true;
}
}








