اذهب إلى المحتوى

لوحة المتصدرين

  1. Ali Ahmed55

    Ali Ahmed55

    الأعضاء


    • نقاط

      6

    • المساهمات

      2040


  2. ياسر مسكين

    ياسر مسكين

    الأعضاء


    • نقاط

      4

    • المساهمات

      2627


  3. محمد_عاطف

    محمد_عاطف

    الأعضاء


    • نقاط

      4

    • المساهمات

      8455


  4. Chihab Hedidi

    Chihab Hedidi

    الأعضاء


    • نقاط

      3

    • المساهمات

      2957


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 12/27/24 في كل الموقع

  1. السلام عليكم هي مكتبه الseaborne فيه بيانات يعني فيه مجموع من البيانات ؟
    3 نقاط
  2. السلام عليكم لو سمحتوا انا من سوريا واخر شهرين مرينا بظروف وما كنت تابع دراسة برمجة وحاسة انوا ضاعت معلومات شو اعمل هل اقوم بالمتابعة ام اعيد جميع ما قمت بدرسته مسبقا؟
    3 نقاط
  3. what is XGboost? how it work? and how to use it
    2 نقاط
  4. السلام عليكم ورحمة الله وبركاته لما أدخل على موقعي تطلع هذه الرسالة URL Error: SSL: no alternative certificate subject name matches target host name '103-link166.quixot.site' المشكلة في التحقق من الشهادة بس كيف أحلها وللعلم الموقع بالوورد برس
    2 نقاط
  5. السلام عليكم لدي جملة استعلام تالية تعرض بيانات بدون تكرار لماذا في كريستال ريبورت تعرض أكثر من مرة بتكرار SELECT dbo.BUYBILL.BUYCODE, dbo.BUYBILL.BUYTYPE, dbo.BUYBILL.BUYDATE, dbo.BUYBILL.IMPORTERNAME, dbo.BUYBILL.NOTES, dbo.BUYBILL.TOTAL, dbo.BUY_DET.ITEMCODE, dbo.BUY_DET.ITEMNAME, dbo.BUY_DET.PRICE, dbo.BUY_DET.QTY, dbo.BUY_DET.TOTAL AS Expr1 FROM dbo.BUYBILL INNER JOIN dbo.BUY_DET ON dbo.BUYBILL.BUYCODE = dbo.BUY_DET.BUYCODE; رغم انه فعلت خيار Suppress If Duplicated وقم بوضع علامة بجانبه. لزالت تظهر مشكلة يتكرر سطر ثلاثة مرات لكنه فارغ فقط ما الحل سبب انه datagridview تجلب منتجات اخر فاتورة void createdatatable() { dt.Columns.Add("رقم الصنف"); dt.Columns.Add("اسم الصنف"); dt.Columns.Add("سعر الشراء"); dt.Columns.Add("الكمية "); dt.Columns.Add(" الاجمالي"); dataGridView1.DataSource = dt; } try { if (IMPORTERNAME.SelectedIndex < 0) { MessageBox.Show("يرجي اختيار اسم الزبون", "تنبيه"); IMPORTERNAME.Select(); return; } if (BUYTYPE.SelectedIndex < 0) { MessageBox.Show("يرجي اختيار نوع الفاتورة", "تنبيه"); BUYTYPE.Select(); return; } if (dataGridView1.Rows.Count == 0) { MessageBox.Show("لاتوجد أصناف لحفظها", "تنبيه"); return; } DataTable dt = new DataTable(); SqlDataAdapter adp = new SqlDataAdapter("select *from buybill where buycode='" + BUYCODE.Text + "'", Class1.con); adp.Fill(dt); if (dt.Rows.Count > 0) { int code = Class1.CODE_GENE("BUYBILL", "ID") + 1; BUYCODE.Text = code.ToString(); } else { DataRow dr = dt.NewRow(); dr["BUYCODE"] = BUYCODE.Text; dr["BUYTYPE"] = BUYTYPE.Text; dr["IMPORTERNAME"] = IMPORTERNAME.Text; dr["NOTES"] = NOTES.Text; dr["BUYDATE"] = BUYDATE.Value; dr["TOTAL"] = Convert.ToDecimal(total_.Text); dr["TOTAL_ARBIC"] = totalar.Text; dr["TOTALQTY"] = Convert.ToInt32( totalqty.Text); dt.Rows.Add(dr); SqlCommandBuilder save = new SqlCommandBuilder(adp); adp.Update(dt); adp = new SqlDataAdapter("SELECT *FROM BUY_DET", Class1.con); adp.Fill(dt); for(int i=0;i<dataGridView1.Rows.Count;i++) { DataRow dr_ = dt.NewRow(); dr_["BUYCODE"]= BUYCODE.Text; dr_["ITEMCODE"] = dataGridView1.Rows[i].Cells[0].Value; dr_["ITEMNAME"] = dataGridView1.Rows[i].Cells[1].Value; dr_["PRICE"]= dataGridView1.Rows[i].Cells[2].Value; dr_["TOTAL"] = total_.Text; dr_["QTY"] = dataGridView1.Rows[i].Cells[3].Value; dt.Rows.Add(dr_); SqlCommandBuilder cmd_ = new SqlCommandBuilder(adp); adp.Update(dt); string itemCode = dataGridView1.Rows[i].Cells[0].Value.ToString(); int qty = Convert.ToInt32(dataGridView1.Rows[i].Cells[3].Value); UpdateItemQuantity(itemCode, qty); } MessageBox.Show(" تم حفظ بيانات فاتورة بنجاح وتحديث كمية في المخزن ", "رسالة تأكيد", MessageBoxButtons.OK, MessageBoxIcon.Information); dataGridView1.DataSource = ""; button1_Click(null, null); } } catch(Exception ex) { MessageBox.Show(ex.Message); } كود حفظ وتعبئة داتا قريد فيو
    1 نقطة
  6. السلام عليكم هي اي دي C() في مكتبه الstatsmodels وامتي استخدمها وهل هي لها استخدمات تاني غير ان استخدمها مع الداله OLS ؟
    1 نقطة
  7. كنت عايز استفسر عن المعاد اللي ابعت فيه وحد يرد عليا عشان ببعت بعض الاسأله في الصباح الباكر بعد الفجر محدش بيرد اي هو المعاد
    1 نقطة
  8. السلام عليكم هذه المساله من leetcode لا حظت انه عند وضع الزيادة قبل اسم المتغير يعطي نتائج صحيحه علي عكس اذا قمت بالزيادة بشكل طبيعي هنا يعطي خطا ويظهر نواتج 5 5 5 اذا قمت بالاستدعاء الاتي /** * const counter = createCounter(5) * counter.increment(); // 6 * counter.reset(); // 5 * counter.decrement(); // 4 */ ما السبب var createCounter = function(init) { let present = init; return { increment:()=> present++, decrement:()=> present--, reset:()=> present = init, } };
    1 نقطة
  9. مكتبة Seaborn في Python هي مكتبة متقدمة لإنشاء الرسوم البيانية وتُستخدم بشكل أساسي لتحليل البيانات وتصوير العلاقات الإحصائية، ;id وهي تحتوي على مجموعة من مجموعات البيانات المدمجة التي يمكن استخدامها كعينات لتجربة الرسوم البيانية والبدء في تحليل البيانات وهذه البيانات مدمجة داخل المكتبة وتستخدم غالبا في الأمثلة التعليمية والتطبيقات التجريبية ولكن البيانات المدمجة في Seaborn صغيرة الحجم وتستخدم أساسا في التعلم وتجربة المكتبة لذا إذا كنت تعمل على مشاريع تحليل بيانات فعلية، ستحتاج عادة إلى استيراد بياناتك من مصادر خارجية كملفات CSV وقواعد بيانات يمكنك إيجاد المزيد من المعلومات من هنا:
    1 نقطة
  10. وعليكم السلام ورحمة الله وبركاته . نعم مكتبة Seaborn تحتوي على مجموعة من البيانات المدمجة التي يمكنك استخدامها لتحليل البيانات والرسومات البيانية. وإليك بعض المجموعات المشهورةفي Seaborn تشمل: tips: تحتوي على بيانات تخص الفواتير والإكراميات في المطاعم مع تفاصيل مثل قيمة الفاتورة، مقدار الإكرامية، الجنس، اليوم، والفئة الزمنية. iris: تحتوي على بيانات خاصة بأزهار الإيريس، مع معلومات عن أطوال الأوراق والأزهار لأنواع مختلفة من الزهور. titanic: تحتوي على بيانات تتعلق بركاب سفينة تيتانيك، مثل ما إذا كانوا قد نجاوا أو لا، العمر، الجنس، الفئة الاجتماعية، وغيرها. diamonds: تحتوي على بيانات تتعلق بالألماس، مثل الحجم، اللون، النقاء، السعر، وغيرها من الخصائص. وإليك رابط github لجميع البيانات المتاحة والملفات أيضا الخاصة بها : https://github.com/mwaskom/seaborn-data ويمكنك تحميل البيانات من خلال الدالة import seaborn as sns # تحميل مجموعة بيانات iris كمثال tips = sns.load_dataset('iris')
    1 نقطة
  11. الدالة C() في مكتبة statsmodels تستخدم لتصنيف المتغيرات (categorical variables) في النماذج الإحصائية ويتم استخدامها لتحويل المتغيرات النوعية (categorical variables) إلى متغيرات وهمية (dummy variables) تلقائيا، مما يسمح بإدراجها في نماذج الانحدار الخطي أو غيرها من النماذج الإحصائية وعند استخدام الدالة OLS لإجراء تحليل الانحدار، فإن C() تستخدم لتضمين المتغيرات النوعية. بدلا من إدخال المتغير النوعي كرقم (مثل 1، 2، 3) أين يتم تحويله إلى متغيرات وهمية بحيث يمكن للنموذج التعامل معه بشكل صحيح. و C() يقوم بتشفيره إلى متغيرات رقمية متعددة تمثل الفئات، مما يساعد النموذج على التعامل معها بشكل صحيح دون الحاجة لتحويلها يدويا وهذا باستخدام طرق مثل pandas.get_dummies(). ويتم استخدامه عادة عند التعامل مع المتغيرات النوعية في تحليل الانحدار أو في نماذج أكثر تعقيدا مثل النماذج المختلطة (Mixed Models) أو تحليل التباين (ANOVA) كما تتيح خيارات إضافية مثل تحديد ترتيب الفئات أو نوع الترميز المستخدم (مثل التأثيرات بدلا من الترميز الوهمي) إلى جانب OLS ويمكن استخدامها لإنشاء تفاعلات بين المتغيرات أو تخصيص تمثيل المتغيرات النوعية في أي نموذج إحصائي.
    1 نقطة
  12. نعم مكتبة Seaborn تحتوي على مجموعة مدمجة من البيانات يمكن استخدامها لاختبار الرسوم البيانية وتجربة المكتبة، للوصول إلى هذه البيانات، يمكنك استخدام الدالة seaborn.get_dataset_names() لمعرفة أسماء مجموعات البيانات المتوفرة، ومن ثم تحميل أي منها باستخدام الدالة seaborn.load_dataset() بهذا الشكل: import seaborn as sns # عرض أسماء مجموعات البيانات المتوفرة print(sns.get_dataset_names()) # تحميل مجموعة البيانات 'tips' data = sns.load_dataset('tips') # عرض أول 5 صفوف من البيانات print(data.head()) بالتوفيق إن شاء الله.
    1 نقطة
  13. وعليكم السلام ورحمة الله وبركاته. اعانكم الله ووفقكم ورزقكم الأمان . بخصوص الانقطاع مدة شهرين ليست بالمدة الكبيرة التي تلزم اعادة كل شئ من البداية إذا كنتي بالفعل قد درستي الاساسيات جيدا . ولكن إذا شعرتي بالنسيان يمكنكي مشاهدة الاساسيات مع تسريع الدرس حتي يتم استرجاع المعلومات ويكفي فقط التطبيق سريعا في المشروع العملي والنظر الى الاكواد التي قمتي بكتابتها . ويمكنكي قراءة الاجابات النالية لمزيد من النصائح :
    1 نقطة
  14. السلام عليكم هي اي الداله دي crosstab الموجود في مكتبه pandas واي هي استخدمتها ؟
    1 نقطة
  15. دالة crosstab هي أداة مفيدة جدا لتحليل البيانات وإنشاء جداول تقاطعية (جداول محورية) وتستخدم لحساب تكرار العلاقات بين متغيرين أو أكثر في البيانات والاستخدام الأساسي للدالة كالتالي: pd.crosstab(index, columns) وهذا مثال لنفترض التالي: import pandas as pd data = { 'النوع': ['ذكر', 'أنثى', 'ذكر', 'أنثى', 'ذكر'], 'المدينة': ['القاهرة', 'الإسكندرية', 'القاهرة', 'القاهرة', 'الإسكندرية'] } df = pd.DataFrame(data) result = pd.crosstab(df['النوع'], df['المدينة']) print(result) والناتج سيكون جدول يوضح كم عدد الذكور والإناث في كل مدينة بحيث الصفوف تمثل النوع والأعمدة تمثل المدينة أين يمكنك حساب النسب المئوية: pd.crosstab(df['النوع'], df['المدينة'], normalize='index') إضافة هوامش المجاميع: pd.crosstab(df['النوع'], df['المدينة'], margins=True) تطبيق دوال حسابية مختلفة: pd.crosstab(df['النوع'], df['المدينة'], values=df['العمر'], aggfunc='mean')
    1 نقطة
  16. ما هو الفرق بين الانحدار الخطي باستخدام متغير واحد والفرق بين الانحدار الخطي باستخدام أكثر من متغير ؟
    1 نقطة
  17. الانحدار الخطي هو تقنية إحصائية تستخدم لنمذجة العلاقة بين المتغيرات فهناك نوعان رئيسيان من الانحدار الخطي الأول الانحدار الخطي البسيط (باستخدام متغير واحد) والانحدار الخطي المتعدد (باستخدام أكثر من متغير) واختيار أي نوع من الانحدار يعتمد على طبيعة البيانات والعلاقة بين المتغيرات بالنسبة للنوع الأول المشكلة لنقل أننا نريد دراسة العلاقة بين عدد ساعات الدراسة (التي سنرمز لها بـ X) ودرجات الامتحان (التي سنرمز لها بـ Y) كالتالي: ساعات الدراسة (X) درجات الامتحان (Y) 1 50 2 60 3 70 4 80 5 90 يمكننا استخدام المعادلة التالية: Y=β0+β1X وبعد تحليل البيانات، لنفترض أن النتائج هي: Y=50+10X ولنفسر النتيجة فإن: β0=50 وهذا يعني أنه إذا لم يدرس الطالب (0 ساعات)، ستكون درجته 50. β1=10 هذا يعني أن كل ساعة دراسة إضافية تزيد من الدرجة بمقدار 10 درجات. وبالنسبة للاختيار المتعدد دعنا نضيف متغيرا آخر، وهو عدد الساعات التي يقضيها الطالب في النوم لنرمز له بـ Z ونريد دراسة تأثيرها أيضا على درجات الامتحان كالتالي: ساعات الدراسة (X) ساعات النوم (Z) درجات الامتحان (Y) 1 6 50 2 5 60 3 8 70 4 7 80 5 8 90 وهنا يمكننا استخدام المعادلة التالية: Y=β0+β1X+β2Z بعد تحليل البيانات، لنفترض أن النتائج هي: Y=40+8X+5Z أي أنه: β0=40: إذا لم يدرس الطالب (0 ساعات) ولم ينم، ستكون درجته 40. β1=8: كل ساعة دراسة إضافية تزيد من الدرجة بمقدار 8 درجات. β2=5: كل ساعة نوم إضافية تزيد من الدرجة بمقدار 5 درجات. بالنسبة لسؤالك الجديد في الانحدار الخطي المتعدد، يمثل: b1,b2,…,bn تأثيرات المتغيرات المستقلة المختلفة على المتغير التابع Y وكل 𝑏𝑖 (حيث 𝑖 هو رقم المتغير) يعكس مقدار تغير Y عند زيادة xi بوحدة واحدة، مع ثبات بقية المتغيرات رغم وجود عدة معاملات (ميول)، فإن النموذج يمثل علاقة واحدة بين المتغيرات المستقلة وY، ويستخدم لتحديد أفضل خط (أو سطح) ملائم يحقق أفضل تطابق بين القيم المتوقعة والملاحظة.
    1 نقطة
  18. y = b0 + b1 * x1 + b2 * x2 + ... + bn * xn في الانحدار الخطي المستقيم باستخدام متغير واحد y = b0 + b1 * x يكون لb0 هو الثابت أو ال Intercept ويكون b1 هو الميل أو slope في المعادلة الانحدار الخطي باستخدام أكثر من متغير لا أفهم ماذا يعني b1, b2 , bn هل هو يعني أن أكثر من ميل وهل ينفع أن يكون في المعادلة أكثر من ميل لأن هكذا سيكون أكثر من خط ونحن نحتاج أن نحسب the best fit line ؟
    1 نقطة
  19. الفرق بين الانحدار الخطي باستخدام متغير واحد والانحدار الخطي باستخدام أكثر من متغير يكمن في عدد المتغيرات المستقلة المستخدمة للتنبؤ بالمتغير التابع. في الانحدار الخطي البسيط، يتم استخدام متغير مستقل واحد فقط لتوقع المتغير التابع، ويكون النموذج بسيطًا لتحليل العلاقة بين متغيرين فقط والصيغة هي: y = b0 + b1 * x حيث x هو المتغير المستقل، وy هو المتغير التابع، وb0 هو التقاطع، وb1 هو الميل يناسب هذا النموذج العلاقات بين متغيرين فقط. أما في الانحدار الخطي المتعدد، فيشمل النموذج عدة متغيرات مستقلة، ويكون النموذج أكثر تعقيدا لتحليل البيانات متعددة الأبعاد والصيغة هي: y = b0 + b1 * x1 + b2 * x2 + ... + bn * xn حيث x1, x2, ..., xn هي المتغيرات المستقلة، وb1, b2, ..., bn هي المعاملات التي توضح تأثير كل متغير مستقل على المتغير التابع. يستخدم الانحدار الخطي البسيط للعلاقات البسيطة بين متغيرين، بينما يستخدم الانحدار المتعدد للعلاقات الأكثر تعقيدا التي تشمل عدة متغيرات.
    1 نقطة
  20. الانحدار الخطي باستخدام متغير واحد (الانحدار الخطي البسيط) يقوم بتحديد علاقة خطية بين متغير مستقل واحد (X) ومتغير تابع (Y). و يستخدم الانحدار الخطي البسيط لتحليل العلاقة بين متغيرين فقط وهذه هي المعادلة الخاصة به: Y = β0 + β1X حيث Y هو المتغير التابع و X هو المتغير المستقل و β0 هو معامل الانحدار و β1 همعدل التغيير في Y بالنسبة لتغيير X. أما بالنسبة إلى الانحدار الخطي باستخدام أكثر من متغير (الانحدار الخطي المتعدد) يقوم بتحديد علاقة خطية بين عدة متغيرات مستقلة (X1 X2 ..... Xn) ومتغير تابع (Y) و يستخدم هذا الانحدار الخطي المتعدد لتحليل العلاقة بين عدة متغيرات وهذه هي المعادلة الخاصة به: Y = β0 + β1X1 + β2X2 + … + βnXn حيث Y هو المتغير التابع و (X1 X2 ..... Xn) هي المتغيرات المستقلة و β0 هو معامل الانحدار و ( β1 β2 ... βn ) هي معدلات التغيير في Y بالنسبة لتغيير كل متغير مستقل.
    1 نقطة
  21. بالنسبة للإنحدار الخطي باستخدام متغير واحد يعتمد على علاقة بين متغير مستقل واحد ومتغير تابع، و في هذا النوع الهدف هو إيجاد معادلة خطية تمثل هذه العلاقة، حيث يكون شكل المعادلة هو y=mx+cy = mx + c، حيث mm هو الميل وcc هو التقاطع، و يستخدم هذا النموذج في الحالات التي يكون فيها المتغير المستقل كافياً للتنبؤ بالمتغير التابع. أما الانحدار الخطي باستخدام أكثر من متغير ، فيأخذ في الاعتبار أكثر من متغير مستقل للتنبؤ بالمتغير التابع، و تكون المعادلة الخطية في هذه الحالة على الشكل: y=b0+b1x1+b2x2+⋯+bnxn ، حيث يمثل كل xix_i متغير مستقل، وbib_i هي المعاملات المرتبطة بهذه المتغيرات، و يتميز هذا النموذج بقدرته على التعامل مع بيانات أكثر تعقيدا، حيث يمكنه تفسير التأثير المشترك لمجموعة من العوامل على المتغير التابع.
    1 نقطة
  22. وعليكم السلام ورحمة الله وبركاته. الدالة crosstab تقوم بإنشاء جدول تقاطع (Cross Tabulation Table) وهو جدول تكراري يساعد في تلخيص البيانات وتصنيفها بناء على عدة متغيرات. وتستقبل الدالة العديد من المعاملات : index: وهي القيم التي يتم إستخدامها كمحور للصفوف (rows). columns: القيم التي يتم إستخدامها كمحور للأعمدة (columns). normalize: إذا كانت True، يتم تطبيع القيم (عرض القيم كنسب مئوية). dropna: يتم حذف القيم الفارغة (NaN) إذا تم تمرير True لهذا المعامل. وتستخدم في العديد من الأمور مثل حساب التكرارات للقيم لديك و أيضا عمل تجميع (aggregate) للقيم لديك . ويمكنك قراءة التوثيق الرسمي لها لمزيد من التفاصيل : https://pandas.pydata.org/docs/reference/api/pandas.crosstab.html
    1 نقطة
  23. الدالة crosstab في مكتبة Pandas تستخدم لإنشاء جداول تقاطع، و تظهر العلاقة بين متغيرين أو أكثر بطريقة منظمة وسهلة الفهم، و تعمل على عد التكرارات لكل مزيج من القيم بين الأعمدة والصفوف، كما يمكنها تلخيص القيم باستخدام دوال إحصائية مثل المجموع أو المتوسط عبر معامل aggfunc، و تعتبر أداة قوية لتحليل البيانات واستخراج التوزيعات أو الأنماط، مع إمكانية إضافة مجاميع الصفوف والأعمدة، وتطبيع النتائج إلى نسب مئوية، و تستخدم بشكل شائع في استكشاف البيانات واستخراج إحصائيات تلخيصية لتقديم رؤى واضحة عن العلاقات بين المتغيرات.
    1 نقطة
  24. وعليكم السلام ورحمة الله وبركاته، دالة crosstab في pandas هي أداة قوية لتحليل البيانات تستخدم لإنشاء جداول تقاطعية تظهر العلاقة بين متغيرين أو أكثر في مجموعة البيانات بحيث تقوم الدالة بحساب التكرارات أو القيم المجمعة عند تقاطع المتغيرات ويمكن استخدامها مع خيارات متعددة مثل margins=True لإضافة المجاميع الكلية، وnormalize=True لعرض النسب المئوية بدلا من العدد على سبيل المثال يمكننا تحليل مبيعات المنتجات حسب المنطقة، أو تصنيف العملاء حسب الفئة العمرية والجنس والصيغة الأساسية للدالة هي: pd.crosstab(index, columns, values=None, aggfunc=None) حيث index وcolumns هما المتغيران المراد تحليل علاقتهما، وvalues هو عمود القيم المراد تجميعها وهو اختياري بينما aggfunc هي دالة التجميع المستخدمة مثل sum أو mean وهذه الدالة مفيدة بشكل خاص في التحليل الإحصائي وتحليل البيانات الاستكشافي.
    1 نقطة
  25. السلام عليكم كما نعلم ان في لارافل الاصدار الحديث 11 تم تغيير ترتيب الملفات و تم حذف الملف kernel.php الذي كان يتم فيه تسجيل المدل وير الذي يتم انشائه middleware سؤالي هو كيف يمكنني التعديل على المدل وير (auth and guest ) التي يتم انشائها بشكل تلقائي مع الحزمه breeze شكرا لكم
    1 نقطة
  26. الطبقات الوسيطة التي ذكرتها (auth و geust) لا يتم إنشاؤها مع الحزمة Breeze فهي لا علاقة لها بالحزمة بشكل خاص وإنما تأتي مع إطار العمل نفسه و Breeze يستعملها عند تعريف المسارات الخاصة بعملية المصادقة والتسجيل وغيرها، كما هو الحال طبعاً مع Jetstream و Fortify ... الطبقة الوسيطة guest عملها هو عدم السماح للمستخدم المصادق عليه بالوصول إلى مسارات الزوار أو بشكل أدق المسارات المطبق عليها هذه الطبقة وأذكر هنا مسار تسجيل الدخول و مسار تسجيل مستخدم جديد على سبيل المثال. (يعني لو مستخدم x سجل دخوله في التطبيق وحاول تعديل الرابط لزيارة صفحة تسجيل الدخول لن يتمكن من الوصول لها بل سيتم إعادة توجيهه إلى صفحة dashboard نفس الأمر بالنسبة لبقية المسارات المطبق عليها هذه الطبقة). الطبقة الوسيطة auth تعمل عكس guest فهي تحمي مسارات المستخدم من الوصول من طرف الزوار، يعني لو زائر قام بتوجيه الطلب مباشرة إلى مسار dashboard على سبيل المثال من دون تسجيل الدخول هذه الطبقة ستُعيد توجيهه إلى مسار تسجيل الدخول ولن تسمح له بهذا الشيء. في غالب الأحيان لا نحتاج التعديل على هذا السلوك و إنما إذا احتجنا إلى التعديل سيكون في الأغلب المسار الذي نريد توجيه المستخدم أو الزائر له، يعني لو الحالة هي أننا نريد توجيه المستخدم المصادق عليه إذا أراد الوصول إلى مسارات guest إلى مسار غير dashboard فيمكن ذلك ببساطة عبر التابع boot في الصنف AppServiceProvider بالشكل التالي: use Illuminate\Auth\Middleware\RedirectIfAuthenticated; // in boot method RedirectIfAuthenticated::redirectUsing(fn($request) => route('my-space')); و تُحدد المسار الذي تريد، وإن كان لديك منطق معقد لتحديد مسار التوجيه يُمكنك من خلال تغيير الدالة السهمية إلى دالة مجهولة عادية وتنفيذ المنطق ثم إرجاع المسار use Illuminate\Auth\Middleware\RedirectIfAuthenticated; // in boot method RedirectIfAuthenticated::redirectUsing(function($request) { // do what you want return route('my-space'); }); بهذا الشكل إذا أراد مستخدم مصادق عليه الوصول إلى login مثلاً سيتم توجيهه إلى مسار my-space وليس الإفتراضي (dashboard)، بطبيعة الحال يجب تعريف هذا المسار وإلا سيعطيك خطأ أن المسار غير معرف. وهكذا نفس الأمر بخصوص الطبقة auth. أيضاً يُمكن تحقيق ما تم ذكره أعلاه من خلال التعديل في الملف app.php الموجود في مجلد bootstrap من خلال التابع withMiddleware عبر إستعمال التوابع redirectTo و redirectUsersTo و redirectGuestsTo على حسب الحالة، في الأسفل بعض الأمثلة: ->withMiddleware(function (Middleware $middleware) { // $middleware->redirectTo('/', '/my-space'); // $middleware->redirectUsersTo('/my-space'); // $middleware->redirectGuestsTo('/'); // $middleware->redirectUsersTo(fn ($request) => route('my-space')); }) أما إن كان لابد من تعديل الصنف الإفتراضي وتخصيصه بالشكل الذي ترغب فعليك إنشاء صنف Middleware مثلاً: pa make:middleware RedirectIfAuthenticated ثم عمل override للصنف الإفتراضي وذلك من خلال تسجيلها بنفس الإسم: ->withMiddleware(function (Middleware $middleware) { $middleware->alias([ 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, ]); }) بعد ذلك تستطيع التعديل على الصنف الذي أنشأته بالشكل الذي تريد، كما يُمكنك عمل extends للصنف الإفتراضي وتخصيص الجزء الذي تريد فقط: <?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; class RedirectIfAuthenticated extends \Illuminate\Auth\Middleware\RedirectIfAuthenticated { protected function redirectTo(Request $request): ?string { return route('my-space'); } }
    1 نقطة
  27. في Laravel 11، تم تغيير بنية الملفات وتبسيط إدارة الـ middleware بحيث تم إزالة ملف Kernel.php، وقد تكون عملية إدارة الـ middleware مختلفة بعض الشيء. للعثور على الـ middleware الأساسية مثل auth وguest وتعديلها فهم لم ينشأوا بشكل تلقائي لذلك اذا كنت تريد التعديل عليهم يجب انشائهم يدويا php artisan make:middleware Authenticate php artisan make:middleware RedirectIfAuthenticated ثم يجب تسجيل الـ Middleware في ملف bootstrap/app.php لكي يتمكن Laravel من التعرف على الـ middleware الجديدة، يجب تسجيلها في ملف bootstrap/app.php. أضف التالي: ->withMiddleware(function (Middleware $middleware) { $middleware->alias([ 'auth' => \App\Http\Middleware\Authenticate::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, ]); }) ويمكنك التعديل علي الملفات التي تم إنشاؤه في مجلد app/Http/Middleware وقم بتعديلها. على سبيل المثال، لملف Authenticate.php: namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; class Authenticate { public function handle($request, Closure $next) { if (Auth::guest()) { return redirect('/login'); } return $next($request); } } بعد تسجيل الـ middleware، يمكنك استخدامها في المسارات الخاصة بك: use Illuminate\Support\Facades\Route; Route::middleware('auth')->group(function () { Route::get('/dashboard', function () { // محتوى الصفحة المحمية }); }); Route::middleware('guest')->group(function () { Route::get('/login', function () { // محتوى صفحة تسجيل الدخول }); });
    1 نقطة
  28. السلام عليكم اريد شرح كتابي تفصيلي مع الامثله لأستخدام المعامل الفارغ الامن Null Safe Operator في لغة php شكرا لكم .
    1 نقطة
  29. إذا كنت قد استخدمت معامل الدمج الفارغ (null coalescing operator) في الماضي، فربما لاحظت أيضًا عيوبه: لا يعمل الدمج الفارغ في استدعاءات التوابع. بدلاً من ذلك، تحتاج إلى اختبارات تحقق وسيطة، أو تعتمد على المعامل optional المتاح في بعض الأطر: $startDate = $subscription->getStartDate(); $dateAsString = $startDate ? $startDate->asDateTimeString() : null; يوفر المعامل (null safe) وظائف مشابهة للمعامل (null coalescing)، ولكنه يدعم أيضًا استدعاءات التوابع. بدلاً من كتابة هذا: <?php $country = null; if ($session !== null) { $user = $session->user; if ($user !== null) { $address = $user->getAddress(); if ($address !== null) { $country = $address->country; } } } الإصدار الثامن من PHP يسمح لك بكتابة: $country = $session?->user?->getAddress()?->country; فهو يتحقق إن كان أي من الكائنات في السلسلة قيمته null فإنه يُعيد null دون حدوث خطأ، أما إن كان هناك كائن فإنه يستدعي الخاصية أو التابع. يُمكن إستخدامه في العديد من الحالات التي تتطلب التحقق و عبارات if كثيرة و الحالات التي نكون فيها نجهل القيمة المعادة من الكائن أو التابع إن كانت null أم قيمة حقيقية.
    1 نقطة
  30. بداية من الإصدار PHP 8.0 ، تم إضافة المعامل الفارغ الآمن Null Safe Operator لتسهيل التعامل مع القيم الفارغة (null) دون حدوث أخطاء. المعامل الفارغ الآمن `?->` يستخدم للوصول إلى خاصية أو طريقة من خلال سلسلة من الكائنات، وإذا كان أي من الكائنات في السلسلة هو قيمة فارغة (null)، فإن المعامل الفارغ الآمن يعود بقيمة فارغة أيضًا بدلاً من حدوث خطأ. لنفترض أن لدينا الكود التالي كمثال: // تعريف الكائنات class User { public function getName() { return "John Doe"; } } class Address { public function getCity() { return "New York"; } } // إنشاء كائنات $user = new User(); $address = new Address(); إذا أردنا الحصول على اسم المستخدم ومدينته، ولكن قد يكون أحد الكائنات غير موجود (قيمة null)، فيمكننا استخدام المعامل الفارغ الآمن كما يلي: // الحصول على اسم المستخدم $name = $user?->getName(); // "John Doe" // الحصول على مدينة العنوان $city = $address?->getCity(); // "New York" // الحصول على اسم المدينة إذا كانت متاحة أو قيمة فارغة إذا كانت المدينة غير متاحة $cityName = $address?->getCity()?->getName(); // null في المثال الأول، يتم الوصول إلى طريقة `getName()` من خلال الكائن `$user`، ونحصل على قيمة الاسم بشكل صحيح. في المثال الثاني، يتم الوصول إلى طريقة `getCity()` من خلال الكائن `$address`، ونحصل على قيمة المدينة بشكل صحيح. في المثال الثالث، نقوم بالوصول إلى طريقة `getCity()` من خلال الكائن `$address`، ومن ثم نحاول الوصول إلى طريقة `getName()` من خلال القيمة المُعادة من `getCity()`، ولكنها تعود بقيمة فارغة (null)، لذلك يتم إرجاع قيمة فارغة (null) للمتغير `$cityName`. باستخدام المعامل الفارغ الآمن، يمكنك تبسيط التعامل مع القيم الفارغة وتجنب حدوث أخطاء غير مرغوب فيها عند الوصول إلى خصائص أو طرق في سلسلة من الكائنات.
    1 نقطة
  31. وعليكم السلام، في الأساس، المعامل الفارغ الآمن يُستخدم للتحقق من وجود القيم في الكائنات والمصفوفات بشكل آمن دون الحاجة للتحقق يدويًا ودون رمي استثناءات أو اظهار أخطاء في حالة عدم وجود القيم .. الأمر الذي يساعد على جعل الشفرة أكثر إتقانًا وقراءةً وصيانةً. تخيل السيناريو التالي: يوجد لدينا صنف User و Profile بحيث يمتلك الأول خاصية profile، في حين يمتلك الثاني خاصية باسم name class User { public $profile = null; public function __construct($profile = null){ if(!is_null($profile)){ $this->profile = $profile; } } } class Profile { public $name = null; public function __construct($name){ $this->name = $name; } } بحيث لما ننشئ مستخدما جديدا، نحن نتحكم فيما إن كان يمتلك بروفايلا أو لا. هذا البروفايل فيه بياناته الشخصية على سبيل الاسم name وغيرها. في السابق وبدون المعامل الفارغ، كنا نقوم بالمقاربة التالية لاستخراج الخاصية name من خلال user: $profile = new Profile('ahmed'); $user = new User($profile); $name = null; // تصريح قيمة افتراضية لمتغير باسم name if ($user !== null && $user->profile !== null && $user->profile->name !== null) { $name = $user->profile->name; // تخزين الاسم في متغير } echo $name; // إما قيمة الاسم إذا كان موجودًا أو null إذا لم يكن موجودًا. أما الآن فسيكفينا كتابة السياق التالي: $name = $user?->profile?->name; echo $name; بدون المعامل الفارغ سوف تحتاج القيام بالكثير من التحققات، لأنك لو حاولت قراءة name مباشرة من خلال: $name = $user->profile->name; سوف يظهر لك خطأ على نحو: Warning: Attempt to read property "name" on null in /home/user/scripts/code.php on line 23
    1 نقطة
  32. يسألني الناس أينما ذهبت - في المؤتمرات، المحاضرات، لدى وكالات تطوير المواقع وغيرها - عن ملف composer.lock. يبدو وكأن الأمر يتعلّق بلغز يزرع الشكوك حول المعمورة! أقدّم لك هذا المقال لتوضيح ماهية هذا الملف وفكّ اللغز الذي يمثّله. يعدّ Composer أداة تدير الإصدارات الخاصة بمكتبات PHP التي يستخدمها المطوّرون في مشاريعهم البرمجية. سأفترض - لأغراض هذا المقال - أنه سبق لك استخدام Composer في مشاريع سابقة. فلنفترض أن لدينا مشروع PHP جديدا ندير اعتماديّاته Dependencies عن طريق Composer. نبدأ بملف composer.json الذي يُستخدَم لإعداد لائحة بالاعتماديّات التي نريد تثبيتها. يبدو الملف على النحو التالي: { "require": { "assassins/ezio": "1.1.0", "assassins/edward": "1.1.2", "templars/shay": "1.1.*", } } عرّفنا بوضوح الإصدارات التي نحتاجها بالنسبة للحزمتين الأولى والثانية؛ إلا أن الأمر مختلف قليلا يالنسبة للحزمة الثالثة templars/shay التي حدّدنا لها بطريقة أكثر مرونة فلم نعرّف إصدار الترقيع Patch version؛ وبالتالي سيكون أي ترقيع للإصدار 1.1 مناسبا للمشروع. تنبغي ملاحظة أن هذه الأسماء المذكورة في الشفرة أعلاه هي أسماء مفترضة لحزم وليست حزما حقيقية يمكن تثبيتها. يمكن القول إن ملف composer.json هو دليل “تقريبي” للإصدارات التي نريد تثبيتها؛ فاستخدام ماسك المكان * يجعل إصدارات عدّة متوافرة لاستخدامها. بمعنى آخر، يحدّد الملف هامشا مقبولا لهرميّة الاعتماديّات في التطبيق. لا يوجد لدينا لحدّ الساعة، أي في بداية المشروع، ملفّ composer.lock؛ إلا أنه سيظهر بعد تنفيذنا للأمر composer install. نجد مباشرة بعد تنفيذ الأمر composer install ملفّا غريبا باسم composer.lock في المجلّد الجذر للمشروع. إن ألقيت نظرة على ما بداخله فستجد أنه كبير نوعا ما. حان الوقت الآن لكشف اللّغز. في الواقع؛ الملف composer.json هو دليل تقريبي - كما قلنا - لإصدارات الاعتماديّات التي يتوجّب على Composer تثبيتها، بينما الملف composer.lock هو تسجيل دقيق بالإصدارات التي ثُبِّتت عند تنفيذ الأمر composer install. أي أنه يسجّل ما ثبّته Composer من مكتبات لمشروعك. في ما يلي مثال بسيط: "source": { "type": "git", "url": "https://github.com/templars/shay.git", "reference": "98c313c831e5d99bb393ba1844df91bab2bb5b8b" }, هل ترى سلسلة المحارف الطويلةَ تلك؟ هذا هو المعرّف الدقيق لإيداع Commit الإصدار المثبّت عندما اتّبع Composer تعليمات composer.json. يحتفظ الملف composer.lock كذلك بجميع إصدارات الاعتماديّات التي تتطلّبها اعتماديّات المشروع؛ والمكتبات التي تقوم عليها اعتماديّات اعتمديّات المشروع.. وهكذا دواليك. يعني هذا أن الملف composer.lock يحوي التسلسل الهرمي الكامل لاعتماديّات التطبيق. في ماذا يفيد وجود التسلسل الهرمي لاعتماديّات المشروع في الملف composer.lock؟ حسنا؛ يمكن أن تجرّب حذف المجلّد الذي توجد به اعتماديّات المشروع، مثلا vendor في Laravel؛ ثم تنفيذ الأمر composer install من جديد. سيجد Composer هذه المرة أن لديك ملفّ composer.lock وبدلا من البحث عن إصدارات متوافقة مع تعليمات الملف composer.jsonفسيلجأ إلى الإصدارات الدقيقة المذكورة في الملف composer.lock ويثبّتها. يعني هذا أننا سنحصُل على نفس المكتبات التي حذفناها بحذف مجلّد الاعتماديّات. سؤال آخر.. هل يجب تضمين الملف composer.lock في مستودع Git؟ يجب أن تكون الإجابة الآن واضحة. إن أردت تسجيل الإصدارات الدقيقة للاعتماديّات التي استخدمتها في المشروع فالإجابة هي نعم؛ وهذا هو الواقع في أغلب المشاريع. إن كنت تعمل ضمن فريق مطوّرين فإن جعل الملف composer.lock في المستودع يضمن أن الجميع يستخدم نفس الإصدارات؛ الأمر الذي يمكن أن يكون مفيدا في تنقيح Debugging الأخطاء التي تظهر لدى مطوّر واحد فقط من الفريق. إن كنت توزّع تطبيقك عبر Git فإن تضمين الملف composer.lock في المستودع سيضمن أن إصدارات الاعتماديّات التي استخدمتها في التطوير وأجريت عليها الاختبارات هي نفسها المستخدمة في بيئة الإنتاج. لماذا من المهم استخدام نفس إصدارات الاعتماديّات؟ فلنفترض أن Git يتجاهل وجود الملف composer.lock. تنفّذ الأمر composer install، يبحث Composer عن آخر ترقيع للإصدار 1.1 من الحزمة templars/shay فيجد الإصدار 1.1.4 ويثبّته. تعمل على المشروع باستخدام الإصدار 1.1.4، وفي هذه الأثناء يقدّم فريق الحزمة templars/shay الإصدار 1.1.5 الذي - لسوء الحظ - يتضمّن علة برمجيّة Bug حرجة. عندما تنشُر مشروعك على بيئة الإنتاج يثبّت Composer - بالاعتماد على تعليمات الملف composer.json - الإصدار 1.1.5 من الحزمة الذي يحوي علّة تمنع تطبيقك من العمل على النحو الذي تريده. يمكنك استنتاج أنه لو كان الملف composer.json في المستودع لأدّى تنفيذ الأمر composer install في بيئة الإنتاج إلى تثبيت الإصدار 1.1.4 من الحزمة templars/shay الذي سبق لك اختبار التطبيق معه. باختصار: في الأخير.. متى يتغيّر الملف composer.lock ولأي سبب؟ أرى طوال الوقت مطورين ينفّذون الأمر composer update كلّما حدّثوا الملف composer.json، للحصول على الحزم الجديدة التي أضافوها إلى الملف. في الواقع هذا الأمر خاطئ! يجب أن تستخدم الأمر composer install بدلا من ذلك، إذ أنه يثبّت الحزم الجديدة دون تحديث إصدارات الحزم الأخرى؛ هذه الطريقة آمن كثيرا. في ما يلي لائحة بإجراءات تتسبّب في تحديث الملف composer.lock: تنفيذ الأمر composer install للمرة الأولى. يُنشَأ الملف composer.lock لتسجيل الإصدارات الدقيقة للاعتماديّات المثبّتة. تنفيذ الأمر composer install بعد إضافة حزم جديدة. يُضاف الإصدار الدقيق للحزمة إلى الملف composer.lock. تنفيذ الأمر composer update. تُحدَّث إصدارات جميع الحزم إلى الترقيع الأخير بما يتوافق مع تعليمات الملف composer.json، وهو ما ينتُج عنه تحديث الإصدارات الدقيقة في الملف composer.lock. تنفيذ الأمر composer update package/name لتحديث الحزمة المذكورة إلى آخر ترقيع، بما يتوافق مع تعليمات الملف composer.json، وبالتالي يُحدَّث الملف composer.lock ليعكس التغيير الحاصل في إصدار الحزمة. يعني ما سبق أن composer install أمر “آمن”، ولن ينتُج عنه سوى إضافة حزم جديدة إلى الملف composer.lock (وليس تحديث حزم موجودة مسبقا). في حين أن الأمر composer update أمر “خطِر”، إذ أنه يتسبّب في تغيير مباشر على الإصدارات الدقيقة الموجودة في الملف composer.lock . أرجو أن يكون الملف اللغز composer.lock قد اتّضح لك بعد قراءة هذا المقال. إن كنت تعلّمت شيئا أو اثنين من هذا المقال فأرجو أن تشاركه مع أصدقائك حتى يعرفوا هم أيضا سر الملف العظيم. ترجمة - بتصرّف - للمقال PHP: The Composer Lock File لصاحبه Dayle Rees. حقوق خلفية الصورة البارزة محفوظة لـ Freepik
    1 نقطة
  33. مقدمة يعدّ توزيع الحِمل Load balancing مكوِّنا أساسيًّا في البنى التحتية عالية التوفر Highly-available، إذ يكثر استخدامه لتحسين الأداء والثبات في مختلف الخدمات على الشبكة؛ بما في ذلك مواقع الوِب، التطبيقات، قواعد البيانات وغيرها. يقوم مبدأ توزيع الحِمل على الاعتماد على أكثر من خادوم وتوزيع العمل المطلوب إنجازه بينها. يوضّح المخطّط التالي بنية تحتية لموقع وِب بدون توزيع حِمل. يتصل الزائر في هذا المثال بخادوم الوِب مباشرة، على العنوان yourdomain.com. إن حدث خلل يجعل الخادوم المضيّف للموقع yourdomain.com غير قادر على العمل فإن الوصول إلى هذا الموقع لن يكون متاحا. علاوةً على ذلك؛ إن أراد الكثير من الزوّار الوصول إلى الموقع في نفس اللحظة ولم يستطع الخادوم التعامل معهم بالسرعة المطلوبة فإن تنزيل صفحات الموقع سيصير بطيئًا، وربما يصبح خارج الخدمة. يمثّل الخادوم في هذه الحالة نقطة إخفاق Point of failure بالنسبة للبنية التحتية، فتوقفه عن العمل يجعل البنية بجميع مكوّناتها خارج الخدمة. يمكن التخفيف من تأثير نقطة الإخفاق الوحيدة هذه بإضافة موزّع حِمل Load balancer وخادوم وِب آخر على الأقل إلى السند الخلفي Backend. تقدّم جميع الخواديم في السند الخلفي نفس المحتوى، فيحصُل الزائر بالتالي على محتوى متجانس بغضّ النظر عن خادوم الوِب الذي أجاب عن طلبه. يتصل الزائر في المخطط أعلاه أولا بموزّع الحِمل الذي يوجّه طلب الزائر إلى خادوم في السند الخلفي. يجيب الخادوم الذي وُجِّه إليه الطلبُ الزائرَ مباشرة. يصبح موزّع الحِمل في هذه الحالة هو نقطة الإخفاق، بمعنى أن توقفه عن العمل يجعل كامل البنية التحتية تتوقف عن العمل. يمكن التغلب على هذا المشكل بإدراج موزّع حِمل ثان؛ إلا أننا سنشرح - قبل أن نناقش هذه الإمكانية - كيفية عمل موزّع الحِمل. ما نوع حركة البيانات التي يمكن لموزع الحمل التعامل معها؟ يستخدم مديرو الأنظمة موزّعات الحمل لإنشاء قواعد توجيه تتعامل أساسا مع أنواع البيانات الأربعة التالية: HTTP: تُوجَّه حركة البيانات في هذه الحالة اعتمادًا على الآليات المعيارية لميثاق HTTP. يعيّن موزّع الحِمل قيم الترويسات X-Forwarded-For، X-Forwarded-Proto وX-Forwarded-Port من أجل تمرير المعلومات الأصلية عن الطلب، أي تلك القادمة من الزائر، إلى الخادوم الذي سيردّ على الطلب . HTTPS: يشبه هذا النوع النوعَ السابق، مع فرق أنه يستخدم التعميّة Encryption. تُعالَج البيانات المعمّاة بإحدى طريقتيْن: تمرير SSL +(أو SSL Passthrough)وتعتمد هذه الطريقة على الاحتفاظ بالتعميّة إلى أن تصل البيانات للخادوم الذي سيجيب على الطلب؛ أما الثانيّة فتُدعى إنهاء SSL (أو SSL Termination) ويوضَع عبء التعميّة وفكّها على موزّع الحمل، غير أن البيانات بين موزّع الحمل وخادوم الوِب تُنقَل دون تعميّة، عكس الطريقة الأولى. TCP: يمكن استخدام ميثاق TCP لتوزيع حركة البيانات بين تطبيقات لا تستخدم HTTP أو HTTPS؛ مثلا بين عنقود Cluster من خواديم قواعد البيانات. UDP: تدعم بعض موزعات الحمل الحديثة توجيه البيانات الخاصّة بمواثيق الإنترنت التي تستخدم حزم UDP مثل نظام أسماء النطاقات DNS وsyslogd. تعرّف قواعدُ التوجيه الميثاقَ والمنفَذ Port على موزّع الحمل وتربطهما بميثاق ومنفَذ موجودين على الخادوم الذي يختاره موزّع الحِمل للإجابة على طلب الزائر. كيف يختار موزّع الحمل خادوما في السند الخلفي؟ يختار موزّع الحمل الخادوم الذي سيتولّى الإجابة على الطلب بناء على عاملَيْن: أولاً؛ يتأكّد موزّع الحمل من قدرة الخادوم على الإجابة على الطلبات التي ترده، ثم يستخدم مجموعة من القواعد المضبوطة مسبقا لاختيار خادوم من بين الخواديم القادرة على الإجابة على الطلب. التحقق من قدرة الخادوم لا يجوز أن توجِّه موزعات الحِمل الطلبات إلى خادوم ليست لديه القدرة على التعامل معها. يراقب موزّع الحمل حالة الخواديم في السند الخلفي بمحاولة الاتصال بها مستخدما الميثاق والمنفَذ المعرَّفيْن في قواعد التوجيه المضبوطة عليه. إن أخفق خادوم في الإجابة على محاولات موزّع الحمل للاتصال به فإن موزع الحمل يعدّه غير قادر على معالجة الطلبات، ويحذفه بالتالي من قائمة الخواديم لديه، فلا يُوجِّه له أي طلب؛ إلى أن يجيب بطريقة مناسبة على محاولات الاتّصال اللاحقة. خوارزميّات توزيع الحِمل تحدّد خوارزميّة خادوما - من بين الخواديم الجاهزة للإجابة - لتوجيه الطلب إليه. تعدّ الخوارزميّات التالية من بين الخوارزميّات الأكثر استخداما في توزيع الحمل: الاختيار الدوري Round robin: تُختار الخواديم في هذه الخوارزميّة بالتتالي. يوجّه موزع الحمل عند استخدام هذه الخوارزمية أول طلب إلى أول خادوم في قائمته، ثم عند وصول الطلب الثاني يوجّهه إلى الخادوم الموالي، وهكذا إلى أن يصل لآخر خادوم في القائمة فيعود للأول. الأقل اتصالات Least connections: يُنصَح بهذه الخوارزميّة عندما تأخذ جلسات الاتصال Sessions آمادا طويلة. يختار الموزّع في هذه الحالة الخادوم ذا الاتصالات النشطة اﻷقل عددا. حسب المصدر Source: يختار موزّع الحمل عند استخدام هذه الخوارزميّة الخادومَ الذي سيجيب على الطلب بناءً على عنوان IP المصدَر، مثلا؛ عنوان IP الزائر. يعني استخدامُ هذه الخوارزميّة أن طلبات زائر معيَّن ستُوجَّه دوما إلى نفس الخادوم. تختلف الخوارزميّات المتاحة للاختيار بينها، حسب التقنيات المستخدمة في موزّع الحمل. كيف تتعامل موزّعات الحِمل مع الحالة State؟ تطلب بعض التطبيقات أن يواصل الزائر الاتصال بنفس الخادوم خلال جلسة الاتصال الواحدة. يمكن عند الاقتضاء استخدام خوارزميّة الاختيار حسب المصدر التي تركّز على عنوان الزائر. توجد طريقة أخرى لتلبية هذه الحاجة، وذلك بتنفيذها على مستوى تطبيق الوِب عبر الجلسات الملتصقة Sticky sessions. إذ يعيّن موزّع الحمل ملف تتبّع Cookie خاصّ بكل جلسة ثم يوجّه الطلبات التابعة لنفس الجلسة إلى نفس الخادوم، اعتمادا على ملف التتبع. تكرار موزّعات الحمل ذكرنا سابقا أن موزّع الحِمل يمكن أن يمثّل نقطة إخفاق إن كان وحيدا، وأنه يمكن تصحيح هذه الوضعية بإضافة موزّع حمل ثان. يتصل موزّع الحِمل الجديد بالأوّل لتشكيل عنقود من خادومَيْ توزيع حِمل يراقب كلّ منهما الآخر ويتأكّد من جاهزيّته لتلقي الطلبات وتوجيهها إلى الخادوم المناسب في المنتهى الخلفي. يمكن لكلٍّ من الخادوميْن في هذه الحالة اكتشاف إخفاق الآخر وعودته إلى العمل. يُحيل نظام أسماء النطاقات DNS المستخدمين إلى موزّع الحِمل الثاني في حال توقّف الأول عن العمل؛ إلا أنّ سجلات أسماء النطاقات يمكن أن تأخذ وقتا حتى يكتمل تحديثها لدى المستخدمين في جميع أنحاء العالم. يلجأ كثير من مديري الأنظمة، للتغلّب على هذا المشكل، إلى وسائل تتيح إعادة تعيين عناوين IP بمرونة، مثل عناوين IP العائمة Floating IPs. تتخلّص هذه الوسائل من مشاكل انتشار السجلات وتحديث التخبئة في سجلات DNS بتوفير عنوان IP ثابت يمكن إعادة تعيينه حسب الحاجة، وبسرعة. لا تغيّر إعادة تعيين IP من العنوان الذي تشير إليه سجلات DNS، إلا أنها تجعل من الممكن نقل عنوان IP نفسه بين خواديم مختلفة. ترجمة - بتصرف - لمقال What is Load Balancing? لصاحبته Melissa Anderson.
    1 نقطة
  34. مقدمة يُستخدم ميثاق (بروتوكول) الوِب TLS (اختصار لـ Transport Layer Security، أمان طبقة النقل) وسلفه SSL (اختصار لـ Secure Sockets Layer، طبقة المقابس الآمنة) لتغليف البيانات العاديّة ضمن إطار محميّ وآمن. يمكن للخواديم باستخدام هذه التقنية أن تؤمّن تبادل البيانات بينها وبين العملاء حتى ولو اعتُرِضت طريقُ الرسائل بين الخادوم والعميل. يساعد نظام الشهادات الأمنية Certificates المستخدِمين والزوار في التحقّق من أمان المواقع التي يتّصلون بها. سنقدّم في هذا الدليل الخطوات اللازمة لإعداد شهادة أمنيّة موقَّعة ذاتيًّا Self-signed certificate لاستخدامها مع خادوم الوِب Apache على أوبونتو 16.04. ملحوظة: تعمّي الشهادات الموقَّعة ذاتيًّا الاتصالات بين الخادوم والعملاء؛ لكن لن يمكنَ للعملاء استخدامُها للتحقّق من التحقّق من هويّة خادومك تلقائيًّا، إذ أنه لم تُوقّعها سلطة معترف بها. تتضمَّن المتصفّحات مثل فيرفكس وكروم قائمة بالسلطات المعترف بها والمخوَّلة إصدار شهادات TLS. يُناسب استخدام الشهادات الموقَّعة ذاتيًّا بيئات الاختبار، على الحاسوب الشخصي أو عندما لا يكون لديك نطاق Domain؛ مثلا في واجهات الوِب غير المتاحة للعموم. إن كان لديك نطاق فالأفضل أن تستخدم شهادة أمنية من سطلة معترف بها. يمكنك الحصول على شهادة مجانيّة من Let’s encrypt وإعدادها. المتطلبات ستحتاج قبل البدء بتنفيذ الخطوات الواردة في هذا الدرس إلى إعداد مستخدم إداري بامتيازات sudo غير المستخدم الجذر. راجع درس الإعداد الابتدائي لخادوم أوبونتو لمعرفة كيفية ذلك. ستحتاج أيضا لتثبيت خادوم الوِب Apache. إن رغبت في تثبيت كامل حزم LAMP (أي لينكس Linux، أباتش Apache، وMySQL وPHP) فالدرس كيف تثبت حزم MySQL ،Apache ،Linux :LAMP و PHP موجود لهذا الغرض؛ أما إن كنت ترغب في تثبيت Apache لوحده فيمكنك الاعتماد على الدرس المُشار إليه مع ترك الخطوات الخاصّة بكلّ من MySQL وPHP. تأكّد من توفّرك على المتطلّبات ثم نفّذ الخطوات المشروحة أدناه. الخطوة اﻷولى: إنشاء شهادة SSL يعمل بروتكول TLS (وسلفه SSL) باستخدام مفتاحيْن للتعميّة واحد عمومي Public وآخر خاصّ (أو سرّي) Private. يُخزَّن المفتاح السّري على الخادوم ولا يجوز أن يطّلع عليه أي عميل فهو خاصّ بالخادوم الذي يستخدمه لتعميّة المحتوى المُرسَل إلى العملاء. يُمكن لأيّ عميل الاطّلاع على شهادة TLS. تحوي هذه الشهادة المفتاح العموميّ الذي يُستخدَم لفكّ التعميّة عن المحتوى القادم من الخادوم. ملحوظة: رغم أن استخدام البروتكول SSL يقلّ يومًا بعد يوم إلا أن المصطلح “شهادة SSL” لا يزال يُستَخدَم كثيرًا، ويُقصَد به - في الغالب - TLS، الذي هو نسخة محسَّنة من SSL. تتيح مكتبة OpenSSL (مكتبة برمجيّة توفّر أدوات للتعامل مع شهادات SSL/TLS) إنشاء مفتاح تعميّة موقَّع ذاتيًّا بالأمر التالي: sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt ستُطرَح عليك مجموعة من الأسئلة، ولكن قبل النظر في تلك الأسئلة سنشرح الخيارات المذكورة في الأمر السابق: openssl: هذا هو الأمر الأساسي لإنشاء الشهادات، المفاتيح وبقية الملفات وإدارتها في OpenSSL. req: يحدّد هذا الأمر الفرعي المعيار X.509 لاستخدامه في البنية التحتيّة التي نريد استخدامها لإدارة المفاتيح العموميّة. يعتمد الميثاقان SSL وTLS المعيار X.509 لإدارة المفاتيح العمومية. نستخدم هذا الأمر الفرعي لطلب إنشاء شهادة تتوافق مع هذا المعيار. x.509: يغيّر هذا الخيار طريقة عمل الأمر الفرعي السابق ليخبره أننا في طور إنشاء شهادة موّقَّعة ذاتيًّا بدلا من إرسال طلب لتوقيع شهادة الذي هو السلوك المبدئي للأمر الفرعي. nodes: يطلُب هذا الخيار من openssl تجاوز خيار تأمين الشهادة بعبارة سرّ Passphrase. نريد أن يكون Apache قادرا على قراءة الشهادة بدون تدخّل من المستخدم عند بدْء تشغيل الخادوم. يمنع وجود عبارة سرّ Apache من قراءة ملفّ الشهادة وسنحتاج عند وجودها لإدخالها في كلّ مرة نعيد فيها تشغيل الخادوم. days 365: يحدّد هذا الخيار مدّة صلاحيّة الشهادة. اخترنا سنة. newkey rsa:2048: يخبر هذا الخيار الأمر openssl أننا نريد توليد شهادة ومفتاح جديد في نفس الوقت. بما أننا لم نولّد المفتاح المطلوب لتوقيع الشهادة في خطوة منفصلة فإننا نحتاج لإنشائه مع الشهادة. يحدّد الجزء rsa:2048 نوعيّة المفتاح بـ RSA وطوله بـ 2048 بت. keyout: يحدّد المسار الذي نريد حفظ المفتاح الخاصّ فيه. out: يحدّد المسار الذي نريد حفظ الشهادة فيه. ستنشئ هذه الخيارات مفاتيح التعميّة والشهادة. يطلُب الأمر كما أسلفنا الإجابة على بضعة أسئلة كما في الصورة التالية. تتعلّق الأسئلة بمعلومات عامة من قبيل الدولة والمدينة والمؤسّسة والمنظَّمة المُصدِرة للشهادة إضافة إلى معلومات عن الخادوم. يتعلّق أهمّ الأسئلة المطروحة - السطر Common Name - بالخادوم. يجب أن تجيب باسم النطاق الذي يعمل عليه الخادوم أو - وهو الأكثر شيوعا - عنوان IP العمومي للخادوم. يبدو المحثّ Prompt على النحو التالي: Country Name (2 letter code) [AU]:حرفان يمثّلان الدولة State or Province Name (full name) [Some-State]:اسم المنطقة (المحافظة أو الولاية) Locality Name (eg, city) []:اسم المدينة Organization Name (eg, company) [Internet Widgits Pty Ltd]:اسم المنظَّمة أو الشركة Organizational Unit Name (eg, section) []:اسم الفرع Common Name (e.g. server FQDN or YOUR name) []:عنوان الخادوم Email Address []:بريد المسؤول سيوضع الملفان المنشآن في مجلّدات فرعيّة من المجلّد etc/ ssl/ حسب ماهو محدَّد في الأمر. سنحتاج أيضًا - ما دمنا نتحدَّث عن OpenSSL - إلى إنشاء مجموعة Diffie-Hellman قويّة لتُستخدَم عندما يُناقش الخادوم طريقة نقل البيانات مع العملاء (خطوة من خطوات عدّة ضمن تقنيّة SSL/TLS لتأمين نقل البيانات). ينشئ اﻷمر التالي المطلوب: sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 يمكن أن يستغرق الأمر بضعة دقائق، نحصُل بعدها على مجموعة Diffie-Hellman مناسبة (على المسار etc/ssl/certs/dhparam.pem/) لاستعمالها في إعداداتنا. الخطوة الثانية: إعداد Apache لاستخدام SSL أنشأنا في الخطوة السابقة ملفّيْ الشهادة والمفتاح الخاصّ. نحتاج الآن لضبط Apache للاستفادة من هذيْن الملفّيْن. سنعدّل بضعة إعدادات: سننشئ مقطعا جديدًا في إعدادات Apache لتحديد خيارات إعداد مبدئيّة آمنة لـ SSL. سنعدّل المضيف الافتراضي Virtual host الخاص بـ SSL للإشارة إلى شهادة SSL التي أنشأناها في الخطوة السابقة. سنعدّل المضيف الافتراضي غير المُعمَّى ليعيد توجيه جميع الطلبات إلى المضيف الافتراضي المُعمَّى (الخاص بـ SSL). يُنصَح بهذا الإجراء لجعل جميع الاتصالات القادمة إلى الموقع آمنة (تمرّ عبر شهادة SSL). يجدر بالإعدادات التي سنحصُل عليها بعد تنفيذ النقاط المُشار إليها أعلاه أن تكون آمنة. تحديد خيارات إعداد مبدئيّة آمنة في Apache سننشئ أولا ملفّ إعداد جديدًا في Apache نعرّف فيه بعض إعدادات SSL. سنضبُط Apache للعمل بخوارزميّات تعميّة فعّالة ونفعّل بعض الميزات المتقدّمة لمساعدتنا في إبقاء خادومنا آمنا. سيُمكن لأيّ مضيف افتراضي يفعّل SSL. أنشئ ملفّ إعداد جديد ضمن المجلَّد etc/apache2/conf-available/ (مجلَّد إعدادات Apache). سنسمّي هذا الملف بـssl-params.conf حتى يكون واضحًا أنه يتعلّق بمعطيات Parameters إعداد SSL. sudo nano /etc/apache2/conf-available/ssl-params.conf سنعتمد لضبط إعدادات Apache بطريقة آمنة على توصيّات Remy van Elst من موقع Cipherli.st. جُهِّز هذا الموقع لتوفير إعدادات تعميّة جاهزة للاستعمال في أكثر البرمجيّات شيوعًا على الخواديم. ملحوظة توفّر الإعدادات المُقترَحة مبدئيًّا في الموقع أعلاه درجة أمان عاليّة. يمكن أن تأتي هذه الدرجة من الأمان على حساب التوافق مع البرامج العميلة (المتصفّحات أو أنظمة التشغيل القديمة). إن أردت دعم إصدارات قديمة من هذه البرامج فإن الموقع يوفّر إعدادات بديلة للإعدادات المبدئيّة، يمكنك الحصول عليها بالنقر على الرابط “Yes, give me a ciphersuite that works with legacy / old software” وستلاحظ أن الإعدادات تبدّلت. يعتمد الخيار بين النسخة المبدئية من الإعدادات والنسخة البديلة على نوعيّة العملاء التي تريد دعمها. توفّر النسختان أمانًا جيّدًا. سننسخ - لأغراض هذا الدرس - الإعدادات المقترحة، مع إجراء تعديليْن عليها. سنعدّل التعليمة SSLOpenSSLConfCmd DHParameters لتشير إلى ملف Diffie-Hellman الذي أنشأناه في الخطوة الأولى. سنعدّل أيضًا تعليمات الترويسة لتغيير عمل الخاصيّة Strict-Transport-Security وذلك بحذف التعليمة preload. توفّر هذه الخاصيّة أمانًا عاليَّا جدًّا إلا أنها يمكن إن فُعِّلت بدون وعي أو بطريقة غير صحيحة - خصوصًا عند استخدام الميزة preload - أن تؤدّي إلى اختلالات كبيرة في عمل الخادوم. تأكّد عندما تفعِّل هذه الميزة أنك تدرك جيّدًا ما تفعله. # from https://cipherli.st/ # and https://raymii.org/s/tutorials/Strong_SSL_Security_On_Apache2.html SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH SSLProtocol All -SSLv2 -SSLv3 SSLHonorCipherOrder On # تعطيل التعليمة preload في الخاصيّة Strict-Transport-Security # يمكنك إن أردت تفعيل هذه الخاصية وذلك بنزع علامة التعليق # من بداية السطر #Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" # نفس التعليمة السابقة ولكن دون preload Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains" Header always set X-Frame-Options DENY Header always set X-Content-Type-Options nosniff # Requires Apache >= 2.4 SSLCompression off SSLSessionTickets Off SSLUseStapling on SSLStaplingCache "shmcb:logs/stapling-cache(150000)" # أضفنا هنا المسار إلى ملفّ Diffie-Hellman SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem" احفظ الملفّ ثم أغلقه عندما تكون جاهزا لذلك. تعديل ملف مضيف SSL الافتراضي المبدئي ننتقل الآن إلى الملف المبدئي Default لمضيف SSL الافتراضي الموجود على المسار etc/apache2/sites-available/default-ssl.conf/. إن كنت تستخدم مضيفا اقتراضيًّا آخر فأبدله بالمضيف الافتراضي المبدئي في الأمر أدناه. نأخذ أولًا نسخة احتياطية من الملف: sudo cp /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/default-ssl.conf.bak ثم نفتح ملف المضيف الافتراضي لتحريره: sudo nano /etc/apache2/sites-available/default-ssl.conf يبدو محتوى الملف، بعد نزع أغلب التعليقات، على النحو التالي: <IfModule mod_ssl.c> <VirtualHost _default_:443> ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory /usr/lib/cgi-bin> SSLOptions +StdEnvVars </Directory> # BrowserMatch "MSIE [2-6]" \ # nokeepalive ssl-unclean-shutdown \ # downgrade-1.0 force-response-1.0 </VirtualHost> </IfModule> سنعدّل قليلا على الملف بإعداد تعليمات بريد مدير الخادوم، عنوان، اسم الخادوم… إلخ. كما سنعدّل تعليمة SSL لتشير إلى مسار ملفّيْ الشهادة والمفاتيح. نختُم بنزع التعليق عن خيار يوفّر الدعم للمتصفّحات القديمة لتفعيله. يبدو الملف بعد التعديلات كالتالي: <IfModule mod_ssl.c> <VirtualHost _default_:443> # بريد مدير الخادوم ServerAdmin your_email@example.com # نطاق الخادوم أو عنوان IP الخاص به ServerName server_domain_or_IP DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory /usr/lib/cgi-bin> SSLOptions +StdEnvVars </Directory> # دعم المتصفحات القديمة BrowserMatch "MSIE [2-6]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 </VirtualHost> </IfModule> احفظ الملف ثم أغلقه. إعادة توجيه طلبات HTTP (غير المُعمَّاة) إلى HTTPS يجيب الخادوم بإعداداته الحاليّة على الطلبات الآمنة (HTTPS) وغير الآمنة (HTTP) على حدّ السواء. يُنصَح في أغلب الحالات من أجل أمان أعلى أن تُوجَّه طلبات HTTP تلقائيَّا إلى HTTPS. نفتح ملف المضيف الافتراضي - أو المضيف الذي تريده - لتحريره: sudo nano /etc/apache2/sites-available/000-default.conf كلّ ما نحتاجه هو إضافة تعليمة إعادة إعادة التوجيه Redirect داخل إعداد الوسم VirtualHost والإشارة إلى النسخة الآمنة من الموقع (https): <VirtualHost *:80> . . . Redirect "/" "https://your_domain_or_IP/" . . . </VirtualHost> احفظ الملف ثم أغلقه. الخطوة الثالثة: تعديل الجدار الناري إن كان جدار ufw الناري مفعّلًا، وهو ما توصي به الدروس المُشار إليها في المتطلّبات، فقد تحتاج لتعديل إعداداتِه من أجل السماح للبيانات المُؤَمَّنة (عبر SSL). يُسجّل Apache أثناء تثبيته مجموعات من المعلومات المختصرة Profiles لدى جدار ufw الناري. يمكننا عرض المجموعات المتوفّرة بالأمر التالي: sudo ufw app list تظهر مُخرجات الأمر : Available applications: Apache Apache Full Apache Secure OpenSSH يمكنك عرض الإعداد الحالي بالأمر sudo ufw status إن كان إعدادك الحالي يسمح لطلبات HTTP فقط فستبدو إعداداتك كالتالي” Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Apache ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Apache (v6) ALLOW Anywhere (v6) يمكننا تفعيل المجموعة Apache Full للسماح لطلبات HTTPS وHTTP معًا، ثم حذف المجموعة Apache لأننا لم نعد بحاجة إليها، فهي متَضَمَّنة في المجموعة Apache Full : sudo ufw allow 'Apache Full' sudo ufw delete allow 'Apache' ملحوظة: يمكنك استخدام الأمر sudo ufw app info PROFILE حيث PROFILE اسم مجموعة المعلومات لمعرفة المنافذ Ports والبروتوكولات التي تسمح المجموعة للطلبات بالمرور عبرها. يجب أن تبدو حالة الجدار الناري الآن على النحو التالي: sudo ufw status المخرجات: Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Apache Full ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Apache Full (v6) ALLOW Anywhere (v6) الخطوة الرابعة: اعتماد التغييرات في Apache نحن جاهزون الآن، بعد أن عدّلنا الإعدادات، لتفعيل وحدات Modules الترويسات Headers وSSL في Apache، وتفعيل المضيف الافتراضي الجاهز لاستخدام SSL ثم إعادة تشغيل Apache. يفعّل الأمران التاليّان على التوالي mod_ssl (وحدة SSL في Apache) وmod_headers (وحدة الترويسات) اللتين تحتاجهما إعداداتنا للعمل: sudo a2enmod ssl sudo a2enmod headers ثم نفعّل المضيف الافتراضي (ضع اسم المضيف مكان default-ssl إن كنت تستخدم مضيفًا غير المضيف المبدئي): sudo a2ensite default-ssl نحتاج أيضًا لتفعيل ملفّ الإعداد ssl-params الذي أنشأناه سابقا: sudo a2enconf ssl-params يجدر بالوحدات المطلوبة أن تكون الآن مفعَّلة وجاهزة للعمل، بقي لنا فقط اعتماد التغييرات. لكن قبل ذلك سنتأكّد من أنه لا توجد أخطاء صياغة في الملفات التي أعددناها وذلك بتنفيذ الأمر التالي: sudo apache2ctl configtest إن جرى كلّ شيء على ما يُرام فستظهر رسالة تشبه ما يلي: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message Syntax OK السطر الأول ليس سوى رسالة تفيد بأنّ التعليمة ServerName غير مضبوطة لتعمل على كامل الخادوم (مثلا مضبوطة في المضيفات الافتراضية فقط). يمكنك التخلّص من هذه الرسالة - إن أردت - بضبط قيمة التعليمة ServerName على نطاق الخادوم أو عنوان IP الخاصّ به في ملف الإعدادات العام etc/apache2/apache2.conf/. هذا الإعداد اختياري، فالرسالة لا تتسبّب في أي خلل. تظهر في السطر الثاني نتيجة التحقّق من الصياغة Syntax OK وتفيد بأنه لا توجد مشكلة من هذه الناحيّة. يمكننا إذن إعادة تشغيل خادوم الوِب لاعتماد التعديلات: sudo systemctl restart apache2 الخطوة الخامسة: اختبار التعمية افتح متصفّح الوِب وأدخل العنوان //:https متبوعًا باسم نطاق الخادوم أو عنوان IP الخاصّ به: https://server_domain_or_IP بما أنّ الشهادة الأمنيّة التي أنشأناه لا تصدُر من سلطة شهادات يثق بها المتصفّح فستظهر صفحة مخيفة عند زيارة الموقع تحمل الرسالة التالية. هذا السلوك متوقَّع وطبيعي. نهتمّ في هذا الدرس بجانب التعميّة من الشهادات الأمنيّة دون جانب التحقّق من هويّة المضيف (الموقع) الذي توفّره سلطات الشهادات (وهو جانب مهمّ أيضًا لأمان التصفّح). انقر على زرّ ADVANCED ثم انقر على الرابط الذي ينقلك إلى موقعك (يوجد عادة أسفل الصفحة). ستُنقَل إلى صفحة الموقع. إن نظرت إلى شريط العناوين في المتصفّح فسترى صورة قفل عليه علامة x أمام عنوان الموقع. يعني هذا الرّمز أن المتصفّح لم يستطع التحقّق من هوية الشهادة، إلا أنه يعمّي الاتصال بينك والخادوم. إن أعددتَ إعادة توجيه طلبات HTTP إلى HTTPS فيمكنك التحقق من نجاح الأمر بالذهاب إلى العنوان http://server_domain_or_IP (بدون حرف s في http). إن ظهرت نفس الأيقونة السابقة في شريط العناوين فهذا يعني نجاح الإعداد. الخطوة السادسة: جعل إعادة التوجيه دائما إن كنت متأكّدًا من رغبتك في السماح للطلبات الآمنة فقط (القادمة عبر HTTPS)، وتحقّقت في الخطوة السابقة من عمل توجيه طلبات HTTP إلى HTTPS فيجب عليك جعل إعادة التوجيه دائمة. افتح ملف إعداد المضيف الافتراضي الذي نريد: sudo nano /etc/apache2/sites-available/000-default.conf نبحث عن سطر إعادة التوجيه الذي أضفناه في خطوة سابقة ثم نضيف إليه الكلمة المفتاحية permanent على النحو التالي: <VirtualHost *:80> . . . Redirect permanent "/" "https://your_domain_or_IP/" . . . </VirtualHost> احفظ الملف ثم أغلقه. ملحوظة: إعادة التوجيه التي أعددناها في الخطوة الثانية باستخدام التعليمة Redirect فقط هي من النوع 302. تصبح إعادة التوجيه هذه من النوع 301 (الفرق بين إعادة التوجيه 301و302) عند إضافة الكلمة المفتاحية permanent (دائم) إلى التعليمة. نتحقّق من خلو الإعدادات من أخطاء في الصياغة: sudo apache2ctl configtest ثم عندما يكون كلّ شيء على ما يرام نعيد تشغيل خادوم الوِب: sudo systemctl restart apache2 ترجمة - بتصرّف للمقال How To Create a Self-Signed SSL Certificate for Apache in Ubuntu 16.04 لصاحبه Justin Ellingwood.
    1 نقطة
×
×
  • أضف...