تخطَّ إلى المحتوى

١٠ يوليو ٢٠٢٦

حل خطأ Access denied for user في MySQL بالعربي

شارك المقال:

أول جدار يصطدم به كل من يبدأ ربط تطبيقه بقاعدة SQL:

ERROR 1045 (28000): Access denied for user 'root'@'localhost'
(using password: YES)

الرسالة مخيفة الشكل لكنها من أكثر الرسائل إفصاحًا — فيها ثلاث معلومات: المستخدم (root)، المضيف الذي أتيت منه (localhost)، وهل أرسلت كلمة مرور (YES/NO). لنستخدمها في التشخيص.

الأسباب الأربعة في جدول

السببالعلامة المميزةالحل
لم ترسل كلمة مرورusing password: NOأضف -p أو املأ خانة password
كلمة مرور خاطئةusing password: YESصحّحها أو أعد ضبطها
root عبر auth_socket (أوبنتو)الطرفية العادية تُرفضsudo mysql ثم أنشئ مستخدم تطبيق
المستخدم/المضيف غير متطابقينالتطبيق يُرفض والطرفية تنجحراجع 'user'@'host' و.env

1) using password: NO — أنت لم ترسل شيئًا

mysql -u root          # ❌ بلا -p: لن يسأل عن كلمة المرور أصلًا
mysql -u root -p       # ✅ سيطلبها الآن

وفي الكود: خانة password فارغة أو undefined في الاتصال تعطي نفس النتيجة — افحص قيمها الفعلية قبل أي شيء آخر.

2) على أوبنتو: root لا يعمل بكلمة مرور أصلًا

المفاجأة التي تصدم الجميع: في تثبيتات أوبنتو/دبيان الحديثة، مصادقة root تتم عبر auth_socket — أي عبر هوية مستخدم النظام، لا كلمة مرور:

sudo mysql       # ✅ يدخل مباشرة — لأنك root النظام

ومن الداخل، الممارسة الصحيحة: أنشئ مستخدمًا خاصًا لتطبيقك بدل العبث بـ root:

CREATE USER 'thecodefix'@'localhost' IDENTIFIED BY 'كلمة-مرور-قوية';
GRANT ALL PRIVILEGES ON thecodefix_db.* TO 'thecodefix'@'localhost';
FLUSH PRIVILEGES;

لاحظ أن الصلاحيات على قاعدة التطبيق فقط (thecodefix_db.*) — لو تسربت بيانات الاتصال يومًا تبقى بقية القواعد بأمان.

3) نسيت كلمة مرور مستخدم؟ أعد ضبطها من الداخل

-- ادخل بـ sudo mysql ثم:
ALTER USER 'thecodefix'@'localhost' IDENTIFIED BY 'الكلمة-الجديدة';
FLUSH PRIVILEGES;

ولا تنسَ تحديثها في .env تطبيقك — عدم تطابق .env مع القاعدة هو السبب الأول لحالة "شغّال بالطرفية، مرفوض بالتطبيق".

4) فخ المضيف: 'user'@'localhost' ليس 'user'@'%'

صلاحيات MySQL تُمنح لثنائية مستخدم + مضيف. المستخدم المعرّف من localhost يُرفض إذا اتصل من أي مكان آخر — وحاوية Docker "مكان آخر":

-- اعرف المعرَّف فعلًا:
SELECT user, host FROM mysql.user;

-- تطبيقك يتصل من حاوية/خادم آخر؟ عرّفه للمضيف الصحيح أو للجميع:
CREATE USER 'thecodefix'@'%' IDENTIFIED BY 'كلمة-مرور-قوية';
GRANT ALL PRIVILEGES ON thecodefix_db.* TO 'thecodefix'@'%';

💡 معلومة تنقذ ساعات: localhost يتصل عبر ملف socket بينما 127.0.0.1 يتصل عبر TCP — بعض الإعدادات تعامل الاثنين مختلفَين. إن فشل أحدهما جرّب الآخر في .env.

قائمة تحقّق سريعة

  • اقرأ using password — NO تعني ما أرسلت، YES تعني خاطئة.
  • على أوبنتو: sudo mysql هي بوابة root — ومنها أنشئ مستخدم التطبيق.
  • تطبيقك لا يستخدم root أبدًا — مستخدم خاص بصلاحيات على قاعدته فقط.
  • الطرفية تنجح والتطبيق يفشل؟ → .env أو ثنائية المستخدم@المضيف.
  • بعد أي CREATE/ALTER/GRANT: حدّث .env وأعد تشغيل التطبيق.

الخلاصة

Access denied رسالة دقيقة وليست غامضة: من؟ من أين؟ وبكلمة مرور أم لا؟ جاوب الأسئلة الثلاثة من نص الرسالة نفسها، وتذكّر خصوصية أوبنتو (auth_socket)، وأعطِ تطبيقك مستخدمه الخاص — وستغلق هذا الباب نهائيًّا.

أتقن الاستعلامات في مسار SQL بالعربي، وقارن عوالم القواعد في الفرق بين SQL و NoSQL، وإذا كان خادمك في حاوية فراجع حل خطأ المنفذ المحجوز في Docker.

📚 مصادر رسمية للتعمّق: توثيق SQL في PostgreSQL

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

ما الفرق بين using password: NO و using password: YES؟

NO تعني أن العميل لم يرسل كلمة مرور إطلاقًا — غالبًا نسيت خيار -p أو تركت خانة password فارغة في الكود. YES تعني أن كلمة مرور أُرسلت لكنها خاطئة، أو أن المستخدم نفسه غير موجود بهذا المضيف. هذا التمييز يوفر عليك نصف التشخيص.

لماذا sudo mysql تدخل بلا كلمة مرور بينما mysql -u root -p ترفض؟

لأن root في تثبيتات أوبنتو/دبيان الحديثة يستخدم إضافة auth_socket: الدخول مسموح فقط لمستخدم النظام root نفسه عبر الـ socket، بلا كلمة مرور أصلًا. لذلك sudo mysql تعمل، وأي دخول بكلمة مرور يُرفض حتى لو كانت «صحيحة» — الحل إنشاء مستخدم تطبيق منفصل أو تغيير إضافة مصادقة root.

المستخدم موجود وكلمة المرور صحيحة والتطبيق ما زال مرفوضًا — لماذا؟

غالبًا مشكلة المضيف: المستخدم معرّف كـ 'app'@'localhost' بينما تطبيقك يتصل من حاوية Docker أو خادم آخر فيصل كمضيف مختلف. أنشئ المستخدم بالمضيف الصحيح أو بـ '%' لكل المضيفين (مع كلمة مرور قوية)، وتذكّر أن localhost عبر socket و127.0.0.1 عبر TCP قد يختلفان.

اقرأ أيضًا

تصفّح كل المقالات في المدوّنة، أو ابدأ التعلّم من المسارات و خرائط الطريق.