C# Academy · درس

الرموز المميّزة للتحديث وانتهاء الصلاحية

نفّذوا تجديدًا آمنًا للرموز المميّزة

الدرس 4 من 413 خطوة

الرموز المميّزة للتحديث وانتهاء الصلاحية درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.

مشكلة انتهاء الصلاحية

تتميز رموز الوصول قصيرة العمر بالأمان، لكنها غير مريحة؛ فإجبار المستخدمين على تسجيل الدخول كل 15 دقيقة يقدّم تجربة استخدام سيئة.

الحل هو رمز تحديث، وهو بيانات اعتماد منفصلة أطول عمرًا تُستخدم للحصول على رموز وصول جديدة دون إعادة إدخال كلمة المرور.

// access token: 15 minutes
// refresh token: 7-30 days

ما هو رمز التحديث؟

يكون رمز التحديث عادةً سلسلة عشوائية مبهمة، وليس JWT. وبما أنه طويل العمر، فيجب تخزينه على الخادم حتى يمكن إبطاله.

أنشئوه باستخدام مولّد أرقام عشوائية آمن تشفيريًا.

public static string GenerateRefreshToken()
{
    var bytes = new byte[64];
    using var rng = RandomNumberGenerator.Create();
    rng.GetBytes(bytes);
    return Convert.ToBase64String(bytes);
}

تخزين رموز التحديث

احفظوا كل رمز تحديث مع مالكه ووقت انتهائه وعلامة توضّح ما إذا كان مُبطَلًا. ويتيح لكم ذلك إبطاله عند تسجيل الخروج أو سرقته.

public class RefreshToken
{
    public int Id { get; set; }
    public string Token { get; set; } = default!;
    public int UserId { get; set; }
    public DateTime ExpiresAt { get; set; }
    public bool IsRevoked { get; set; }
}

إصدار الرمزين عند تسجيل الدخول

عند نجاح تسجيل الدخول، أعيدوا رمز الوصول قصير العمر ورمز تحديث جديدًا. واحفظوا رمز التحديث في قاعدة البيانات.

var access = tokenService.CreateAccessToken(user);
var refresh = new RefreshToken
{
    Token = TokenService.GenerateRefreshToken(),
    UserId = user.Id,
    ExpiresAt = DateTime.UtcNow.AddDays(7)
};
db.RefreshTokens.Add(refresh);
await db.SaveChangesAsync();
return Results.Ok(new { access, refresh = refresh.Token });

نقطة نهاية التحديث

تقبل نقطة النهاية المخصصة /refresh رمز تحديث، وتصدر رمز وصول جديدًا تمامًا إذا كان صالحًا.

app.MapPost("/refresh", async (RefreshDto dto, AppDb db, TokenService tokens) =>
{
    var stored = await db.RefreshTokens
        .SingleOrDefaultAsync(r => r.Token == dto.RefreshToken);

    if (stored is null || stored.IsRevoked ||
        stored.ExpiresAt < DateTime.UtcNow)
        return Results.Unauthorized();

    var user = await db.Users.FindAsync(stored.UserId);
    var access = tokens.CreateAccessToken(user!);
    return Results.Ok(new { access });
});

تدوير رموز التحديث

يعزز التدوير أمان التدفق: في كل مرة يُستخدم فيها رمز تحديث، أبطلوه وأصدروا رمزًا جديدًا. وبذلك يصبح الرمز المسروق والمستخدم مسبقًا عديم الفائدة.

stored.IsRevoked = true;            // burn the old one
var next = new RefreshToken
{
    Token = TokenService.GenerateRefreshToken(),
    UserId = stored.UserId,
    ExpiresAt = DateTime.UtcNow.AddDays(7)
};
db.RefreshTokens.Add(next);
await db.SaveChangesAsync();

اكتشاف إعادة استخدام الرمز

يتيح لكم التدوير اكتشاف السرقة: فإذا قُدّم مرة أخرى رمز سبق إبطاله، فاعتبرو ذلك خرقًا أمنيًا وأبطلوا عائلة الرموز بأكملها الخاصة بالمستخدم.

if (stored.IsRevoked)
{
    // This token was already used - likely stolen.
    await RevokeAllUserTokens(stored.UserId, db);
    return Results.Unauthorized();
}

تسجيل الخروج والإبطال

يؤدي تسجيل الخروج ببساطة إلى إبطال رمز التحديث الحالي. وسينتهي رمز الوصول تلقائيًا خلال دقائق.

app.MapPost("/logout", async (RefreshDto dto, AppDb db) =>
{
    var stored = await db.RefreshTokens
        .SingleOrDefaultAsync(r => r.Token == dto.RefreshToken);
    if (stored is not null) stored.IsRevoked = true;
    await db.SaveChangesAsync();
    return Results.Ok();
}).RequireAuthorization();

مكان تخزين الرموز على العميل

بالنسبة إلى المتصفحات، يتمثل النمط الأكثر أمانًا في تخزين رمز التحديث في ملف تعريف ارتباط HttpOnly, Secure حتى لا تتمكن JavaScript من قراءته، مما يحد من سرقته عبر XSS.

يمكن الاحتفاظ برمز الوصول قصير العمر في الذاكرة.

Response.Cookies.Append("refresh", refresh.Token, new CookieOptions
{
    HttpOnly = true,
    Secure = true,
    SameSite = SameSiteMode.Strict,
    Expires = refresh.ExpiresAt
});

تنظيف الرموز المنتهية

تتراكم رموز التحديث. شغّلوا مهمة دورية في الخلفية، مثل خدمة مستضافة، لحذف السجلات المنتهية أو المُبطَلة.

await db.RefreshTokens
    .Where(r => r.ExpiresAt < DateTime.UtcNow || r.IsRevoked)
    .ExecuteDeleteAsync();

اختيار مدد الصلاحية

وازنوا بين الأمان والراحة:

  • رمز الوصول: من 5 إلى 15 دقيقة، للحد من فترة تعرّض الرمز المتسرّب.
  • رمز التحديث: من ساعات إلى أسابيع، بحسب مستوى الحساسية.
  • استخدموا التدوير لأي مدة تتجاوز يومًا واحدًا.
AccessTokenLifetime  = TimeSpan.FromMinutes(15);
RefreshTokenLifetime = TimeSpan.FromDays(7);

اختبار سريع

اختبروا فهمكم لتدفق التحديث.

مراجعة

نفّذتم تدفق رمز التحديث:

  • أصدروا رمز وصول قصير العمر، بالإضافة إلى رمز تحديث طويل ومبهم ومخزّن على الخادم.
  • تستبدل نقطة النهاية /refresh رمز تحديث صالحًا برمز وصول جديد.
  • يعزز التدوير واكتشاف إعادة الاستخدام الحماية من السرقة.
  • خزّنوا رموز التحديث في ملفات تعريف ارتباط HttpOnly ونظّفوا السجلات المنتهية.

وبذلك تكتمل دورة مصادقة JWT.

البدء مجانًا

تعلم C# مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
93
الدروس
346

الأسئلة الشائعة

هل درس «الرموز المميّزة للتحديث وانتهاء الصلاحية» مجاني؟

نعم — نص درس «الرموز المميّزة للتحديث وانتهاء الصلاحية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.

ماذا ستتعلم في «الرموز المميّزة للتحديث وانتهاء الصلاحية»؟

نفّذوا تجديدًا آمنًا للرموز المميّزة تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟

لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «الرموز المميّزة للتحديث وانتهاء الصلاحية»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟

نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. بنية JWT والمطالبات
  2. تهيئة مصادقة JWT Bearer
  3. إصدار الرموز المميّزة
  4. الرموز المميّزة للتحديث وانتهاء الصلاحية
← العودة إلى C# Academy