public async Task LogoutAsync() { var userCode = _workContext.GetUserCode(); if (userCode == Guid.Empty) { return; } var userAgent = NetworkExtension.GetUserAgent(_httpContextAccessor.HttpContext.Request); var localIpAddress = NetworkExtension.GetLocalIpAddress(_httpContextAccessor.HttpContext.Request).ToString(); var remoteIpAddress = NetworkExtension.GetRemoteIpAddress(_httpContextAccessor.HttpContext.Request).ToString(); var repoToken = _uow.GetRepository <ITokenRepository>(); var token = await repoToken.GetByUserAsync(userCode, userAgent, localIpAddress, remoteIpAddress); if (token == null) { return; } await _cache.RemoveAsync($"TokenInfos:{token.Id}"); repoToken.Delete(token); await _uow.CommitAsync(); }
private async Task <TokenInfo> GetTokenAsync(Guid userCode) { var userAgent = NetworkExtension.GetUserAgent(_httpContextAccessor.HttpContext.Request); var localIpAddress = NetworkExtension.GetLocalIpAddress(_httpContextAccessor.HttpContext.Request).ToString(); var remoteIpAddress = NetworkExtension.GetRemoteIpAddress(_httpContextAccessor.HttpContext.Request).ToString(); TokenInfo token = null; //Lấy token từ cache theo IdUser var bytes = await _cache.GetAsync($"Sessions:{userCode}"); if (bytes != null) { var tokenCodes = JsonConvert.DeserializeObject <List <Guid> >(Encoding.UTF8.GetString(bytes)); foreach (var tokenCode in tokenCodes) { bytes = await _cache.GetAsync($"TokenInfos:{tokenCode}"); if (bytes != null) { var tokenInfo = JsonConvert.DeserializeObject <TokenInfo>(Encoding.UTF8.GetString(bytes)); if (tokenInfo.UserAgent == userAgent && tokenInfo.LocalIpAddress == localIpAddress && tokenInfo.PublicIpAddress == remoteIpAddress) { return(tokenInfo); } } } } //Lấy token từ DB còn sử dụng dc theo IdUser if (token == null) { var repoToken = _uow.GetRepository <ITokenRepository>(); var tokens = await repoToken.GetUnexpiredTokenByUserAsync(userCode); token = tokens.FirstOrDefault(x => x.UserAgent == userAgent && x.LocalIpAddress == localIpAddress && x.PublicIpAddress == remoteIpAddress); if (token == null) { return(null); } var idTokens = tokens.Select(x => x.Code).ToList(); await _cache.SetAsync($"Sessions:{userCode}", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(idTokens))); var cacheOption = new DistributedCacheEntryOptions(); cacheOption.AbsoluteExpiration = token.ExpireAt; await _cache.SetAsync($"TokenInfos:{token.Code}", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(token)), cacheOption); } return(token); }
public async Task <TokenModel> LoginAsync(Guid tenantCode, LoginModel model) { model.UserName = model.UserName.ToUpper(); var repoUser = _uow.GetRepository <IUserRepository>(); var user = await repoUser.FindUserByUsernameAsync(tenantCode, model.UserName); if (user == null) { throw new Exception("Tài khoản hoặc mật khẩu không đúng"); } var account = await _userManager.FindByIdAsync(user.Id.ToString()); var result = await _signInManager.CheckPasswordSignInAsync(account, model.Password, true); if (result.IsLockedOut) { throw new Exception("Tài khoản bị khóa"); } if (!result.Succeeded) { throw new Exception("Tài khoản hoặc mật khẩu không đúng"); } //TODO: Xóa các Token đã hết hạn => Đưa vào BackgroundJob //var expired = tokenInfos.Where(x => x.ExpireAtUtc <= DateTime.UtcNow); //if (expired.Any()) //{ // repoToken.DeleteRange(expired); // _uowCore.SaveChanges(); //} SessionModel session; var token = await GetTokenAsync(user.Id); if (token != null) { session = JsonConvert.DeserializeObject <SessionModel>(token.Metadata); } else { var expireIn = TimeSpan.FromDays(1); var tokenCode = Guid.NewGuid(); var expireAt = DateTime.Now.Add(expireIn); var expireAtUtc = DateTime.UtcNow.Add(expireIn); var claims = new List <Claim>(); claims.Add(new Claim(JwtRegisteredClaimNames.Jti, tokenCode.ToString())); claims.Add(new Claim(ClaimTypes.Sid, user.Id.ToString())); claims.Add(new Claim(ClaimTypes.GroupSid, tenantCode.ToString())); var jwt = new JwtSecurityToken( claims: claims, expires: expireAt, signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_options.SecretKey)), SecurityAlgorithms.HmacSha256)); var accessToken = new JwtSecurityTokenHandler().WriteToken(jwt); session = new SessionModel { IdUser = user.Id, UserName = user.UserName, PhoneNumber = user.PhoneNumber, Email = user.Email, CreatedAt = user.CreatedAt, UserInfo = await GetInfoAsync(user.Id), TenantInfo = await GetTenantInfoAsync(user.TenantCode), Claims = await GetClaimsAsync(user.Id) }; token = new TokenInfo { AccessToken = accessToken, CreatedAt = DateTime.Now, CreatedAtUtc = DateTime.UtcNow, ExpireAt = expireAt, ExpireAtUtc = expireAtUtc, Code = tokenCode, IdUser = user.Id, LocalIpAddress = NetworkExtension.GetLocalIpAddress(_httpContextAccessor.HttpContext.Request).ToString(), PublicIpAddress = NetworkExtension.GetRemoteIpAddress(_httpContextAccessor.HttpContext.Request).ToString(), Metadata = JsonConvert.SerializeObject(session), RefreshToken = null, Source = "Application", TimeToLife = expireIn.TotalMinutes, UserAgent = NetworkExtension.GetUserAgent(_httpContextAccessor.HttpContext.Request), TenantCode = tenantCode }; var repoToken = _uow.GetRepository <ITokenRepository>(); await repoToken.InsertAsync(token); await _uow.CommitAsync(); } return(new TokenModel { AccessToken = token.AccessToken, ExpireIn = (token.ExpireAt - DateTime.Now).TotalMinutes, ExpireAt = token.ExpireAt, Timezone = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now).TotalHours, //RefreshToken = account.SecurityStamp, }); }