首先是有效令牌请求,第二个请求中是无效令牌

时间:2017-05-29 03:09:54

标签: c# token jwt

我遇到了使用webapi生成的令牌(jwt)的问题。当它为用户生成令牌时,它会正常访问系统,但是当它再次请求访问系统并生成新令牌时,它会说当我进行任何调用时新生成的令牌无效。

我正在使用webapi asp.net核心。

    private Customer _customer;
    private readonly ICustomerRepository _repository;
    private readonly TokenOptions _tokenOptions;
    private readonly JsonSerializerSettings _serializerSettings;

    public AccountController(IOptions<TokenOptions> jwtOptions, IUow uow, ICustomerRepository repository) : base(uow)
    {
        _repository = repository;
        _tokenOptions = jwtOptions.Value;
        ThrowIfInvalidOptions(_tokenOptions);

        _serializerSettings = new JsonSerializerSettings
        {
            Formatting = Formatting.Indented,
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
    }

    [HttpPost]
    [AllowAnonymous]
    [Route("v1/authenticate")]
    public async Task<IActionResult> Post([FromForm] AuthenticateUserCommand command)
    {
        if (command == null)
            return await Response(null, new List<Notification> { new Notification("User", "Usuário ou senha inválidos") });

        var identity = await GetClaims(command);
        if (identity == null)
            return await Response(null, new List<Notification> { new Notification("User", "Usuário ou senha inválidos") });

        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.UniqueName, command.Username),
            new Claim(JwtRegisteredClaimNames.Jti, await _tokenOptions.JtiGenerator()),
            new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(_tokenOptions.IssuedAt).ToString(), ClaimValueTypes.Integer64),
            identity.FindFirst("ModernStore")
        };

        var jwt = new JwtSecurityToken(
            issuer: _tokenOptions.Issuer,
            audience: _tokenOptions.Audience,
            claims: claims.AsEnumerable(),
            notBefore: _tokenOptions.NotBefore,
            expires: _tokenOptions.Expiration,
            signingCredentials: _tokenOptions.SigningCredentials);

        var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

        var response = new
        {
            token = encodedJwt,
            expires = (int)_tokenOptions.ValidFor.TotalSeconds,
            user = new
            {
                id = _customer.Id,
                email = _customer.Email.Address,
                username = _customer.User.Username
            }
        };

        var json = JsonConvert.SerializeObject(response, _serializerSettings);
        return new OkObjectResult(json);
    }

    private static void ThrowIfInvalidOptions(TokenOptions options)
    {
        if (options == null) throw new ArgumentNullException(nameof(options));

        if (options.ValidFor <= TimeSpan.Zero)
            throw new ArgumentException("O período deve ser maior que zero", nameof(TokenOptions.ValidFor));

        if (options.SigningCredentials == null)
            throw new ArgumentNullException(nameof(TokenOptions.SigningCredentials));

        if (options.JtiGenerator == null)
            throw new ArgumentNullException(nameof(TokenOptions.JtiGenerator));
    }

    private static long ToUnixEpochDate(DateTime date)
        => (long)Math.Round((date.ToUniversalTime() - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalSeconds);

    private Task<ClaimsIdentity> GetClaims(AuthenticateUserCommand command)
    {
        var customer = _repository.GetByUsername(command.Username);

        if (customer == null)
            return Task.FromResult<ClaimsIdentity>(null);

        if (!customer.User.Authenticate(command.Username, command.Password))
            return Task.FromResult<ClaimsIdentity>(null);

        _customer = customer;

        return Task.FromResult(new ClaimsIdentity(
            new GenericIdentity(customer.User.Username, "Token"),
            new[] {
                new Claim("ModernStore", "User")
            }));
    }
}

0 个答案:

没有答案
相关问题