首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我应该把JWT逻辑放在web api中的什么地方?

我应该把JWT逻辑放在web api中的什么地方?
EN

Stack Overflow用户
提问于 2019-06-05 08:38:01
回答 1查看 107关注 0票数 0

所以我有一个api,可以使用JWT创建、登录等等。现在我的Login类太广泛了,对我喜欢的东西有太多的责任。这就是了;

代码语言:javascript
复制
    [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?这方面的标准方法是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-05 08:59:19

你能把所有令牌生成的东西放在一个单独的服务类中吗?然后使用DI注入服务。还可以给它一个接口,这样你就可以更容易地测试它:

代码语言:javascript
复制
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);
    }
}

则您的登录操作可能如下所示:

代码语言:javascript
复制
[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”通常用于静态类,但我想您可以将其放入其中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56452919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档