public async Task <IActionResult> OAuth(string code = null, string state = null) { var now = DateTime.UtcNow; if (string.IsNullOrWhiteSpace(code)) { return(BadRequest()); } if (string.IsNullOrWhiteSpace(state)) { return(BadRequest()); } var trysKey = $"oauthtrys={Request.HttpContext.Connection.RemoteIpAddress}"; var trys = (int?)memoryCache.Get(trysKey); if (trys.HasValue) { memoryCache.Set(trysKey, trys.Value + 1, now.AddMinutes(1)); if (trys.Value > 5) { return(StatusCode(420, $"Too Many Requests. Try again after {now.AddSeconds(70).ToString("o")}")); } } else { memoryCache.Set(trysKey, 1, TimeSpan.FromMinutes(1)); } var storedState = Request.Cookies["state"]; if (storedState != state) { return(BadRequest()); } Response.Cookies.Append("state", "", new CookieOptions { HttpOnly = true, Expires = DateTimeOffset.Now.AddDays(-100), IsEssential = true }); var accessTokenResponse = await discordHttp.GetAccessToken(code); if (!accessTokenResponse.Scopes.Contains("identify") || !accessTokenResponse.Scopes.Contains("guilds")) { return(BadRequest()); } var userReponse = await discordHttp.GetCurrentUser(accessTokenResponse.AccessToken); if (!ulong.TryParse(userReponse.Id, out var userId)) { return(BadRequest()); } var unixTime = now.AddSeconds(accessTokenResponse.ExpiresIn).ToUnixTime(); var authEntry = new AuthEntry { AccessToken = accessTokenResponse.AccessToken, Expires = unixTime, RefreshToken = accessTokenResponse.RefreshToken, Scope = accessTokenResponse.Scope, UserId = userId, Avatar = userReponse.Avatar }; var newAuthEntry = await authRepo.CreateAuthEntry(authEntry); var cookieOptions = new CookieOptions { Expires = DateTimeOffset.FromUnixTimeSeconds(unixTime), HttpOnly = true, IsEssential = true, }; Response.Cookies.Append("key", newAuthEntry.Key, cookieOptions); memoryCache.Set($"key={newAuthEntry.Key}", authEntry, TimeSpan.FromMinutes(1)); return(RedirectToAction("Index", "Home")); }