Где я должен поместить мою логику JWT в мой веб-API? - PullRequest
0 голосов
/ 05 июня 2019

Итак, у меня есть API с create, login и т. Д. С использованием JWT.Прямо сейчас мой класс входа в систему слишком широк и со слишком большой ответственностью за мои симпатии.Вот оно;

    [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)
        });
    }

Мне бы хотелось, чтобы создание моего токена было отделено от методов Контроллера, но я не совсем уверен, каков наилучший подход к этому, так, где это будет принадлежать?Это структура моей папки:

Folder structure

Я не чувствую, что она принадлежит ни одной из моих папок, но, возможно, в помощниках, idk?Каков стандартный подход к этому?

1 Ответ

1 голос
/ 05 июня 2019

Не могли бы вы просто поместить все компоненты генерации токенов в отдельный класс обслуживания? Затем используйте 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
    });
}

С точки зрения того, в какую папку помещать этот класс и интерфейс (должно быть два отдельных файла), это в основном зависит от того, что имеет смысл для вас или вашей команды. Может быть, другая папка называется «Службы», может быть «Аутентификация», может быть «Аутентификация / Услуги». «Помощники», как правило, предназначены для статических классов, но, я думаю, вы могли бы поместить их туда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...