π₯οΈ Login Kodu β C# / ASP.NET Core (.NET 10)
AΕaΔΔ±daki kod, /login sayfasΔ±nΔ±n C# muadilidir (Razor Pages)
π Login.cs (Program.cs'ye eklenecek Razor Pages kodu)
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Osman Website Login β C# / ASP.NET Core (.NET 10) sΓΌrΓΌmΓΌ
// Python (FastAPI) muadili: /opt/hava-durumu/app/main.py iΓ§indeki auth bΓΆlΓΌmΓΌ
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
//
// Program.cs iΓ§ine eklenecek kod. Gereksinimler:
// builder.Services.AddDistributedMemoryCache();
// builder.Services.AddSession(o => { o.Cookie.Name = "osman_session"; });
// app.UseSession();
//
using System.Collections.Concurrent;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
public class LoginModel : PageModel
{
// ββ Ayarlar βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
private const string SessionCookie = "osman_session";
private const string TrustedIp = "90.247.57.179"; // ΓΆzel IP: kalΔ±cΔ± cookie + otomatik tanΔ±ma
private static readonly Dictionary<string, string> Users = new()
{
["u1"] = "p1",
["u2"] = "p2",
};
// token -> (username, expiresUtc). Thread-safe.
private static readonly ConcurrentDictionary<string, (string Username, DateTime Expires)> Sessions = new();
// ββ BaΔlam ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
private readonly IHttpContextAccessor _http;
public LoginModel(IHttpAccessor accessor) => _http = accessor;
// ββ View'a baΔlanan ΓΆzellikler ββββββββββββββββββββββββββββββββββββββ
public string? Username { get; private set; }
public string? ClientIp { get; private set; }
public string? IpSource { get; private set; }
public string? Error { get; private set; }
public string? RemainingText { get; private set; }
public bool OneShot { get; private set; }
// ββ YardΔ±mcΔ±lar βββββββββββββββββββββββββββββββββββββββββββββββββββββ
private (string Ip, string Source) GetClientIp()
{
var ctx = _http.HttpContext!;
var xff = ctx.Request.Headers["X-Forwarded-For"].ToString();
if (!string.IsNullOrWhiteSpace(xff))
return (xff.Split(',')[0].Trim(), "X-Forwarded-For (Traefik proxy ΓΌzerinden)");
return (ctx.Connection.RemoteIpAddress?.ToString() ?? "?", "DoΔrudan baΔlantΔ±");
}
private static (TimeSpan Remaining, DateTime ExpiresLocal) UntilMidnight()
{
var tz = TimeZoneInfo.FindSystemTimeZoneById("Europe/Istanbul");
var nowTr = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tz);
var nextMidnight = nowTr.Date.AddDays(nowTr.TimeOfDay == TimeSpan.Zero ? 0 : 1);
var remaining = nextMidnight - nowTr.TimeOfDay;
return (remaining, nowTr.Date.Add(remaining));
}
private static string Fmt(TimeSpan t) => $"{(int)t.TotalHours} saat {t.Minutes} dakika";
private string? CurrentUser()
{
var ctx = _http.HttpContext!;
if (ctx.Request.Cookies.TryGetValue(SessionCookie, out var token) &&
Sessions.TryGetValue(token, out var sess))
{
if (sess.Expires > DateTime.UtcNow)
return sess.Username;
Sessions.TryRemove(token, out _); // sΓΌresi doldu, temizle
}
return null;
}
private string? SessionRemainingText()
{
var ctx = _http.HttpContext!;
if (ctx.Request.Cookies.TryGetValue(SessionCookie, out var token) &&
Sessions.TryGetValue(token, out var sess) && sess.Expires > DateTime.UtcNow)
{
return Fmt(sess.Expires - DateTime.UtcNow);
}
return null;
}
// ββ GET /login ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
public void OnGet()
{
var (ip, source) = GetClientIp();
ClientIp = ip;
IpSource = source;
Username = CurrentUser();
RemainingText = Username is null ? null : SessionRemainingText();
}
// ββ POST /login βββββββββββββββββββββββββββββββββββββββββββββββββββββ
public IActionResult OnPost(string username, string password)
{
var (ip, source) = GetClientIp();
ClientIp = ip;
IpSource = source;
if (!Users.TryGetValue((username ?? "").Trim(), out var _p) || _p != password)
{
Error = "KullanΔ±cΔ± adΔ± veya Εifre hatalΔ±.";
return Page();
}
var (remaining, _) = UntilMidnight();
var token = Convert.ToHexString(RandomNumberGenerator.GetBytes(16));
Sessions[token] = ((username ?? "").Trim(), DateTime.UtcNow + remaining);
if (ip == TrustedIp)
{
// KalΔ±cΔ± cookie: gece yarΔ±sΔ±na kadar, tarayΔ±cΔ± kapansa bile otomatik tanΔ±nΔ±r
Response.Cookies.Append(SessionCookie, token, new CookieOptions
{
HttpOnly = true,
SameSite = SameSiteMode.Lax,
MaxAge = remaining,
});
Console.WriteLine($"[AUTH] Trusted IP {ip} iΓ§in kalΔ±cΔ± cookie (user={username}, {remaining})");
return RedirectToPage();
}
else
{
// DiΔer IP'ler: cookie YOK, kalan sΓΌre YOK β tek seferlik giriΕ ekranΔ±
Username = (username ?? "").Trim();
OneShot = true;
Console.WriteLine($"[AUTH] {ip} trusted deΔil, cookie yok, tek seferlik giriΕ ekranΔ± (user={username})");
return Page();
}
}
// ββ POST /logout ββββββββββββββββββββββββββββββββββββββββββββββββββββ
public IActionResult OnPostLogout()
{
if (Request.Cookies.TryGetValue(SessionCookie, out var token))
Sessions.TryRemove(token, out _);
Response.Cookies.Delete(SessionCookie);
return RedirectToPage();
}
}
βοΈ Kurulum notlarΔ±
builder.Services.AddDistributedMemoryCache();veAddSession()gerekli- Cookie mantΔ±ΔΔ± Python sΓΌrΓΌmΓΌyle birebir: ΓΆzel IP'ye kalΔ±cΔ± cookie, diΔerlerine tek seferlik ekran
- Oturumlar bellek iΓ§i (restart'ta sΔ±fΔ±rlanΔ±r)