مقدمة: لماذا كلمة المرور الخاصة بك ليست مجرد سلسلة نصية
\n\nتخيل: لقد كتبت تطبيق Java رائعًا لمكتبة عبر الإنترنت. يقوم المستخدمون بالتسجيل، وحفظ الإشارات المرجعية، وكتابة المراجعات. وفجأة — تسرب قاعدة البيانات. جميع كلمات المرور بنص واضح. كارثة؟ بل وأي كارثة! في عام 2024، تحدث تسريبات البيانات كل 39 ثانية، و81% منها مرتبطة بالمصادقة الضعيفة. إذا كنت تكتب بلغة Java وتريد ألا يظهر مشروعك في نشرات الأخبار الإلكترونية — فهذه المقالة لك.
\n\nسنشرح المصادقة الآمنة في تطبيقات Java من الألف إلى الياء: من تجزئة كلمات المرور إلى JWT والحماية من CSRF. بدون نظرية مملة، فقط كود عملي وممارسات حقيقية. هيا بنا!
\n\n1. تجزئة كلمات المرور: خط الدفاع الأول
\n\nالقاعدة الأولى للأمان: لا تقم أبدًا بتخزين كلمات المرور بنص واضح. حتى لو كانت قاعدة البيانات الخاصة بك هي الكأس المقدسة، فإن تشفير كلمات المرور هو الحد الأدنى الإلزامي. في Java، يتم استخدام خوارزميات مثل bcrypt أو scrypt أو Argon2. لماذا لا MD5 أو SHA؟ لأنها سريعة جدًا — سيتمكن المهاجم من تخمين كلمة المرور في ثوانٍ.
\n\nالتطبيق العملي: bcrypt في العمل
\nأضف التبعية في pom.xml (Maven):
<dependency>\n <groupId>org.springframework.security</groupId>\n <artifactId>spring-security-crypto</artifactId>\n <version>6.2.0</version>\n</dependency>\n\n\nالآن نقوم بتجزئة كلمة المرور عند التسجيل:
\nimport org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;\n\npublic class PasswordService {\n private final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();\n\n public String hashPassword(String rawPassword) {\n return encoder.encode(rawPassword); // يولد الملح تلقائيًا\n }\n\n public boolean checkPassword(String rawPassword, String storedHash) {\n return encoder.matches(rawPassword, storedHash);\n }\n}\n\n\nهام: يضيف bcrypt ملحًا عشوائيًا تلقائيًا، لذا حتى كلمات المرور المتطابقة ستبدو مختلفة. عامل التكلفة (cost factor) الافتراضي هو 10، ولكن للأنظمة الحرجة يمكن رفعه إلى 12-14.
\n\n2. JWT (JSON Web Tokens): جلسة خفيفة وآمنة
\n\nبعد التسجيل، يجب على المستخدم تأكيد هويته بطريقة ما. ملفات تعريف الارتباط (Cookies)؟ ممكن، لكن JWT هو المعيار الحديث لواجهات REST API. يحتوي الرمز المميز على معلومات عن المستخدم ويتم توقيعه بمفتاح سري. لا توجد جلسات على الخادم — كل شيء في الرمز المميز.
\n\nإنشاء JWT في Java
\nقم بتوصيل مكتبة io.jsonwebtoken:jjwt:
<dependency>\n <groupId>io.jsonwebtoken</groupId>\n <artifactId>jjwt-api</artifactId>\n <version>0.12.3</version>\n</dependency>\n\n\nتوليد الرمز المميز:
\nimport io.jsonwebtoken.Jwts;\nimport io.jsonwebtoken.security.Keys;\nimport javax.crypto.SecretKey;\nimport java.util.Date;\n\npublic class JwtUtil {\n private final SecretKey key = Keys.hmacShaKeyFor("مفتاح_سري_بطول_لا_يقل_عن_256_بت".getBytes());\n\n public String generateToken(String username) {\n return Jwts.builder()\n .subject(username)\n .issuedAt(new Date())\n .expiration(new Date(System.currentTimeMillis() + 3600000)) // ساعة واحدة\n .signWith(key)\n .compact();\n }\n\n public String extractUsername(String token) {\n return Jwts.parser()\n .verifyWith(key)\n .build()\n .parseSignedClaims(token)\n .getPayload()\n .getSubject();\n }\n}\n\n\nنصيحة: لا تخزن المفتاح السري في الكود! استخدم متغيرات البيئة أو Vault. ولا تضع أبدًا بيانات حساسة (كلمات مرور، أرقام بطاقات) في JWT — يمكن فك تشفير الرمز المميز بدون توقيع.
\n\n