المصادقة ل PHP. بسيطة وخفيفة الوزن وآمنة.
مكتوب مرة واحدة، ليتم استخدامه في كل مكان.
محايد تمامًا للإطار وقاعدة البيانات.
pdo
)mysqlnd
) أو برنامج تشغيل PostgreSQL ( pgsql
) أو برنامج تشغيل SQLite ( sqlite
)openssl
)تضمين المكتبة عبر الملحن [؟]:
$ composer require delight-im/auth
قم بتضمين أداة التحميل التلقائي للملحن:
require __DIR__ . ' /vendor/autoload.php ' ;
إنشاء قاعدة بيانات وإنشاء الجداول المطلوبة:
هل تريد الترحيل من إصدار سابق لهذا المشروع؟ راجع دليل الترقية الخاص بنا للحصول على المساعدة.
// $ db = new PDO ( ' mysql:dbname=my-database ; host = localhost ; charset = utf8mb4' , ' my-username' , ' my-password' ) ;
// or
// $ db = new PDO ( ' pgsql:dbname=my-database ; host = localhost ; port = 5432 ' , ' my-username' , ' my-password' ) ;
// or
// $ db = new PDO ( ' sqlite:../Databases/my-database.sqlite' ) ;
// or
// $ db = Delight D b P doDatabase::fromDsn ( new Delight D b P doDsn ( ' mysql:dbname=my-database ; host = localhost ; charset = utf8mb4' , ' my-username' , ' my-password' ) ) ;
// or
// $ db = Delight D b P doDatabase::fromDsn ( new Delight D b P doDsn ( ' pgsql:dbname=my-database ; host = localhost ; port = 5432 ' , ' my-username' , ' my-password' ) ) ;
// or
// $ db = Delight D b P doDatabase::fromDsn ( new Delight D b P doDsn ( ' sqlite:../Databases/my-database.sqlite' ) ) ;
$ auth = new Delight Auth Auth ( $ db );
إذا كان لديك اتصال PDO
مفتوح بالفعل، فما عليك سوى إعادة استخدامه. يحتاج مستخدم قاعدة البيانات (على سبيل المثال my-username
) إلى الامتيازات SELECT
و INSERT
و UPDATE
و DELETE
على الأقل للجداول التي تستخدمها هذه المكتبة (أو قاعدة البيانات الرئيسية الخاصة بها).
إذا كان خادم الويب الخاص بك خلف خادم وكيل وكان $_SERVER['REMOTE_ADDR']
يحتوي فقط على عنوان IP الخاص بالوكيل، فيجب عليك تمرير عنوان IP الحقيقي للمستخدم إلى المنشئ في الوسيطة الثانية، والتي تسمى $ipAddress
. الافتراضي هو عنوان IP البعيد المعتاد الذي تتلقاه PHP.
إذا كانت جداول قاعدة بياناتك لهذه المكتبة تحتاج إلى بادئة مشتركة، على سبيل المثال my_users
بدلاً من users
(وبالمثل بالنسبة للجداول الأخرى)، قم بتمرير البادئة (على سبيل المثال my_
) كمعلمة ثالثة للمنشئ، والتي تسمى $dbTablePrefix
. هذا أمر اختياري والبادئة فارغة بشكل افتراضي.
أثناء التطوير، قد ترغب في تعطيل تقييد الطلب أو تقييده الذي تقوم به هذه المكتبة. للقيام بذلك، قم بتمرير false
إلى المنشئ باعتباره الوسيط الرابع، والذي يسمى $throttling
. يتم تمكين الميزة بشكل افتراضي.
أثناء مدة الجلسة، قد يتم تغيير بعض بيانات المستخدم عن بعد، إما بواسطة عميل في جلسة أخرى أو بواسطة مسؤول. وهذا يعني أنه يجب إعادة مزامنة هذه المعلومات بانتظام مع مصدرها المعتمد في قاعدة البيانات، وهو ما تفعله هذه المكتبة تلقائيًا. بشكل افتراضي، يحدث هذا كل خمس دقائق. إذا كنت تريد تغيير هذا الفاصل الزمني، فقم بتمرير فاصل زمني مخصص بالثواني إلى المنشئ باعتباره الوسيط الخامس، والذي يسمى $sessionResyncInterval
.
إذا كانت جميع جداول قاعدة البيانات الخاصة بك تحتاج إلى اسم قاعدة بيانات مشترك أو اسم مخطط أو أي مؤهل آخر يجب تحديده بشكل صريح، فيمكنك اختياريًا تمرير هذا المؤهل إلى المنشئ كمعلمة سادسة، والتي تسمى $dbSchema
.
إذا كنت تريد استخدام مثيل PdoDatabase
(على سبيل المثال $db
) بشكل مستقل أيضًا، فيرجى الرجوع إلى وثائق مكتبة قاعدة البيانات.
try {
$ userId = $ auth -> register ( $ _POST [ ' email ' ], $ _POST [ ' password ' ], $ _POST [ ' username ' ], function ( $ selector , $ token ) {
echo ' Send ' . $ selector . ' and ' . $ token . ' to the user (e.g. via email) ' ;
echo ' For emails, consider using the mail(...) function, Symfony Mailer, Swiftmailer, PHPMailer, etc. ' ;
echo ' For SMS, consider using a third-party service and a compatible SDK ' ;
});
echo ' We have signed up a new user with the ID ' . $ userId ;
}
catch ( Delight Auth InvalidEmailException $ e ) {
die ( ' Invalid email address ' );
}
catch ( Delight Auth InvalidPasswordException $ e ) {
die ( ' Invalid password ' );
}
catch ( Delight Auth UserAlreadyExistsException $ e ) {
die ( ' User already exists ' );
}
catch ( Delight Auth TooManyRequestsException $ e ) {
die ( ' Too many requests ' );
}
ملحوظة: وظيفة رد الاتصال المجهول هي وظيفة إغلاق. وبالتالي، بالإضافة إلى المعلمات الخاصة به، لا تتوفر سوى الكائنات العالمية الفائقة مثل $_GET
و $_POST
و $_COOKIE
و $_SERVER
في الداخل. بالنسبة لأي متغير آخر من النطاق الأصلي، تحتاج إلى توفير نسخة بشكل صريح بالداخل عن طريق إضافة عبارة use
بعد قائمة المعلمات.
اسم المستخدم في المعلمة الثالثة اختياري. يمكنك تمرير null
هناك إذا كنت لا ترغب في إدارة أسماء المستخدمين.
إذا كنت ترغب في فرض أسماء مستخدمين فريدة، من ناحية أخرى، ما عليك سوى استدعاء registerWithUniqueUsername
بدلاً من register
وكن مستعدًا لالتقاط DuplicateUsernameException
.
ملاحظة: عند قبول أسماء المستخدمين وإدارتها، قد ترغب في استبعاد أحرف التحكم غير القابلة للطباعة وبعض الأحرف الخاصة القابلة للطباعة، كما هو الحال في فئة الأحرف [x00-x1fx7f/:\]
. للقيام بذلك، يمكنك تغليف الاستدعاء إلى Auth#register
أو Auth#registerWithUniqueUsername
داخل فرع شرطي، على سبيل المثال عن طريق قبول أسماء المستخدمين فقط عند استيفاء الشرط التالي:
if ( preg_match ( ' /[x00-x1fx7f/: \\ ]/ ' , $ username ) === 0 ) {
// ...
}
للتحقق من البريد الإلكتروني، يجب عليك إنشاء عنوان URL باستخدام المحدد والرمز المميز وإرساله إلى المستخدم، على سبيل المثال:
$ url = ' https://www.example.com/verify_email?selector= ' . urlencode ( $ selector ) . ' &token= ' . urlencode ( $ token );
إذا كنت لا تريد إجراء التحقق من البريد الإلكتروني، فما عليك سوى حذف المعلمة الأخيرة لـ Auth#register
، أي الوظيفة المجهولة أو الإغلاق. سيكون المستخدم الجديد نشطًا على الفور.
هل تحتاج إلى تخزين معلومات مستخدم إضافية؟ اقرأ هنا.
ملحوظة: عند إرسال بريد إلكتروني إلى المستخدم، يرجى ملاحظة أن اسم المستخدم (الاختياري)، في هذه المرحلة، لم يتم تأكيد قبوله لمالك عنوان البريد الإلكتروني (الجديد) بعد. يمكن أن تحتوي على لغة مسيئة أو مضللة اختارها شخص ليس المالك الفعلي للعنوان.
try {
$ auth -> login ( $ _POST [ ' email ' ], $ _POST [ ' password ' ]);
echo ' User is logged in ' ;
}
catch ( Delight Auth InvalidEmailException $ e ) {
die ( ' Wrong email address ' );
}
catch ( Delight Auth InvalidPasswordException $ e ) {
die ( ' Wrong password ' );
}
catch ( Delight Auth EmailNotVerifiedException $ e ) {
die ( ' Email not verified ' );
}
catch ( Delight Auth TooManyRequestsException $ e ) {
die ( ' Too many requests ' );
}
إذا كنت تريد تسجيل الدخول باستخدام أسماء المستخدمين من ناحية أخرى، إما بالإضافة إلى تسجيل الدخول عبر عنوان البريد الإلكتروني أو كبديل، فهذا ممكن أيضًا. ما عليك سوى استدعاء الأسلوب loginWithUsername
بدلاً من login
للأسلوب. بعد ذلك، بدلًا من التقاط InvalidEmailException
، تأكد من التقاط كل من UnknownUsernameException
و AmbiguousUsernameException
. قد ترغب أيضًا في قراءة الملاحظات حول تفرد أسماء المستخدمين في القسم الذي يشرح كيفية تسجيل مستخدمين جدد.
قم باستخراج المحدد والرمز المميز من عنوان URL الذي نقر عليه المستخدم في رسالة التحقق الإلكترونية.
try {
$ auth -> confirmEmail ( $ _GET [ ' selector ' ], $ _GET [ ' token ' ]);
echo ' Email address has been verified ' ;
}
catch ( Delight Auth InvalidSelectorTokenPairException $ e ) {
die ( ' Invalid token ' );
}
catch ( Delight Auth TokenExpiredException $ e ) {
die ( ' Token expired ' );
}
catch ( Delight Auth UserAlreadyExistsException $ e ) {
die ( ' Email address already exists ' );
}
catch ( Delight Auth TooManyRequestsException $ e ) {
die ( ' Too many requests ' );
}
إذا كنت تريد أن يتم تسجيل دخول المستخدم تلقائيًا بعد التأكيد الناجح، فما عليك سوى الاتصال confirmEmailAndSignIn
بدلاً من confirmEmail
. تدعم هذه الطريقة البديلة أيضًا عمليات تسجيل الدخول المستمرة عبر المعلمة الثالثة الاختيارية الخاصة بها.
عند النجاح، تقوم الطريقتان confirmEmail
confirmEmailAndSignIn
بإرجاع مصفوفة تحتوي على عنوان البريد الإلكتروني الجديد للمستخدم، والذي تم التحقق منه للتو، في الفهرس الأول. إذا كان التأكيد لتغيير العنوان بدلاً من التحقق البسيط من العنوان، فسيتم تضمين عنوان البريد الإلكتروني القديم للمستخدم في المصفوفة عند الفهرس صفر.
تتحكم المعلمة الثالثة للطرق Auth#login
و Auth#confirmEmailAndSignIn
في ما إذا كان تسجيل الدخول مستمرًا باستخدام ملف تعريف ارتباط طويل الأمد. مع تسجيل الدخول المستمر هذا، قد يظل المستخدمون مصادقين لفترة طويلة، حتى عندما تكون جلسة المتصفح مغلقة بالفعل وانتهاء صلاحية ملفات تعريف الارتباط للجلسة. عادةً، ستحتاج إلى إبقاء المستخدم مسجلاً الدخول لأسابيع أو أشهر باستخدام هذه الميزة، والتي تُعرف باسم "تذكرني" أو "أبقني مسجلاً الدخول". سيجد العديد من المستخدمين أن هذا الأمر أكثر ملاءمة، ولكنه قد يكون أقل أمانًا إذا تركوا أجهزتهم دون مراقبة.
if ( $ _POST [ ' remember ' ] == 1 ) {
// keep logged in for one year
$ rememberDuration = ( int ) ( 60 * 60 * 24 * 365.25 );
}
else {
// do not keep logged in after session ends
$ rememberDuration = null ;
}
// ...
$ auth -> login ( $ _POST [ ' email ' ], $ _POST [ ' password ' ], $ rememberDuration );
// . . .
بدون تسجيل الدخول المستمر، وهو السلوك الافتراضي ، سيظل المستخدم مسجلاً للدخول فقط حتى يقوم بإغلاق المتصفح الخاص به، أو طالما تم تكوينه عبر session.cookie_lifetime
و session.gc_maxlifetime
في PHP.
احذف المعلمة الثالثة أو اضبطها على null
لتعطيل الميزة. بخلاف ذلك، يمكنك أن تسأل المستخدم ما إذا كان يريد تمكين "تذكرني". يتم ذلك عادةً من خلال مربع اختيار في واجهة المستخدم الخاصة بك. استخدم الإدخال من مربع الاختيار هذا للاختيار بين المدة null
والمدة المحددة مسبقًا بالثواني هنا، على سبيل المثال 60 * 60 * 24 * 365.25
لمدة عام واحد.
try {
$ auth -> forgotPassword ( $ _POST [ ' email ' ], function ( $ selector , $ token ) {
echo ' Send ' . $ selector . ' and ' . $ token . ' to the user (e.g. via email) ' ;
echo ' For emails, consider using the mail(...) function, Symfony Mailer, Swiftmailer, PHPMailer, etc. ' ;
echo ' For SMS, consider using a third-party service and a compatible SDK ' ;
});
echo ' Request has been generated ' ;
}
catch ( Delight Auth InvalidEmailException $ e ) {
die ( ' Invalid email address ' );
}
catch ( Delight Auth EmailNotVerifiedException $ e ) {
die ( ' Email not verified ' );
}
catch ( Delight Auth ResetDisabledException $ e ) {
die ( ' Password reset is disabled ' );
}
catch ( Delight Auth TooManyRequestsException $ e ) {
die ( ' Too many requests ' );
}
ملحوظة: وظيفة رد الاتصال المجهول هي وظيفة إغلاق. وبالتالي، بالإضافة إلى المعلمات الخاصة به، لا تتوفر سوى الكائنات العالمية الفائقة مثل $_GET
و $_POST
و $_COOKIE
و $_SERVER
في الداخل. بالنسبة لأي متغير آخر من النطاق الأصلي، تحتاج إلى توفير نسخة بشكل صريح بالداخل عن طريق إضافة عبارة use
بعد قائمة المعلمات.
يجب عليك إنشاء عنوان URL باستخدام المحدد والرمز المميز وإرساله إلى المستخدم، على سبيل المثال:
$ url = ' https://www.example.com/reset_password?selector= ' . urlencode ( $ selector ) . ' &token= ' . urlencode ( $ token );
إذا لم يعمل العمر الافتراضي لطلبات إعادة تعيين كلمة المرور بالنسبة لك، فيمكنك استخدام المعلمة الثالثة لـ Auth#forgotPassword
لتحديد فاصل زمني مخصص بالثواني يجب أن تنتهي صلاحية الطلبات بعده.
في الخطوة التالية، سينقر المستخدمون على الرابط الذي تلقوه. قم باستخراج المحدد والرمز المميز من عنوان URL.
إذا كان زوج المحدد/الرمز المميز صالحًا، فاسمح للمستخدم باختيار كلمة مرور جديدة:
try {
$ auth -> canResetPasswordOrThrow ( $ _GET [ ' selector ' ], $ _GET [ ' token ' ]);
echo ' Put the selector into a "hidden" field (or keep it in the URL) ' ;
echo ' Put the token into a "hidden" field (or keep it in the URL) ' ;
echo ' Ask the user for their new password ' ;
}
catch ( Delight Auth InvalidSelectorTokenPairException $ e ) {
die ( ' Invalid token ' );
}
catch ( Delight Auth TokenExpiredException $ e ) {
die ( ' Token expired ' );
}
catch ( Delight Auth ResetDisabledException $ e ) {
die ( ' Password reset is disabled ' );
}
catch ( Delight Auth TooManyRequestsException $ e ) {
die ( ' Too many requests ' );
}
وبدلاً من ذلك، إذا لم تكن بحاجة إلى أي رسائل خطأ ولكنك تريد فقط التحقق من الصلاحية، فيمكنك استخدام الإصدار الأبسط قليلاً:
if ( $ auth -> canResetPassword ( $ _GET [ ' selector ' ], $ _GET [ ' token ' ])) {
echo ' Put the selector into a "hidden" field (or keep it in the URL) ' ;
echo ' Put the token into a "hidden" field (or keep it in the URL) ' ;
echo ' Ask the user for their new password ' ;
}
الآن بعد أن أصبح لديك كلمة المرور الجديدة للمستخدم (ولا يزال لديك المعلومات الأخرى)، يمكنك إعادة تعيين كلمة المرور:
try {
$ auth -> resetPassword ( $ _POST [ ' selector ' ], $ _POST [ ' token ' ], $ _POST [ ' password ' ]);
echo ' Password has been reset ' ;
}
catch ( Delight Auth InvalidSelectorTokenPairException $ e ) {
die ( ' Invalid token ' );
}
catch ( Delight Auth TokenExpiredException $ e ) {
die ( ' Token expired ' );
}
catch ( Delight Auth ResetDisabledException $ e ) {
die ( ' Password reset is disabled ' );
}
catch ( Delight Auth InvalidPasswordException $ e ) {
die ( ' Invalid password ' );
}
catch ( Delight Auth TooManyRequestsException $ e ) {
die ( ' Too many requests ' );
}
هل تريد أن يقوم المستخدم المعني بتسجيل الدخول تلقائيًا عند نجاح إعادة تعيين كلمة المرور الخاصة به؟ ما عليك سوى استخدام Auth#resetPasswordAndSignIn
بدلاً من Auth#resetPassword
لتسجيل دخول المستخدم على الفور.
إذا كنت بحاجة إلى معرف المستخدم أو عنوان البريد الإلكتروني، على سبيل المثال لإرسال إشعار إليه بأن كلمة المرور الخاصة به قد تمت إعادة تعيينها بنجاح، فما عليك سوى استخدام القيمة المرجعة لـ Auth#resetPassword
، وهي عبارة عن مصفوفة تحتوي على إدخالين باسم id
و email
.
إذا كان المستخدم مسجل الدخول حاليًا، فيمكنه تغيير كلمة المرور الخاصة به.
try {
$ auth -> changePassword ( $ _POST [ ' oldPassword ' ], $ _POST [ ' newPassword ' ]);
echo ' Password has been changed ' ;
}
catch ( Delight Auth NotLoggedInException $ e ) {
die ( ' Not logged in ' );
}
catch ( Delight Auth InvalidPasswordException $ e ) {
die ( ' Invalid password(s) ' );
}
catch ( Delight Auth TooManyRequestsException $ e ) {
die ( ' Too many requests ' );
}
إن مطالبة المستخدم بكلمة المرور الحالية ( والقديمة قريبًا) والمطالبة بها للتحقق هي الطريقة الموصى بها للتعامل مع تغييرات كلمة المرور. هذا مبين أعلاه.
إذا كنت متأكدًا من أنك لا تحتاج إلى هذا التأكيد، فيمكنك استدعاء changePasswordWithoutOldPassword
بدلاً من changePassword
وإسقاط المعلمة الأولى من استدعاء الطريقة (والتي قد تحتوي على كلمة المرور القديمة).
على أية حال، بعد تغيير كلمة مرور المستخدم، يجب عليك إرسال بريد إلكتروني إلى عنوان البريد الإلكتروني الرئيسي لحسابه كإشعار خارج النطاق لإعلام مالك الحساب بهذا التغيير المهم.
إذا قام المستخدم بتسجيل الدخول حاليًا، فيمكنه تغيير عنوان بريده الإلكتروني.
try {
if ( $ auth -> reconfirmPassword ( $ _POST [ ' password ' ])) {
$ auth -> changeEmail ( $ _POST [ ' newEmail ' ], function ( $ selector , $ token ) {
echo ' Send ' . $ selector . ' and ' . $ token . ' to the user (e.g. via email to the *new* address) ' ;
echo ' For emails, consider using the mail(...) function, Symfony Mailer, Swiftmailer, PHPMailer, etc. ' ;
echo ' For SMS, consider using a third-party service and a compatible SDK ' ;
});
echo ' The change will take effect as soon as the new email address has been confirmed ' ;
}
else {
echo ' We can ' t say if the user is who they claim to be ' ;
}
}
catch ( Delight Auth InvalidEmailException $ e ) {
die ( ' Invalid email address ' );
}
catch ( Delight Auth UserAlreadyExistsException $ e ) {
die ( ' Email address already exists ' );
}
catch ( Delight Auth EmailNotVerifiedException $ e ) {
die ( ' Account not verified ' );
}
catch ( Delight Auth NotLoggedInException $ e ) {
die ( ' Not logged in ' );
}
catch ( Delight Auth TooManyRequestsException $ e ) {
die ( ' Too many requests ' );
}
ملحوظة: وظيفة رد الاتصال المجهول هي وظيفة إغلاق. وبالتالي، بالإضافة إلى المعلمات الخاصة به، لا تتوفر سوى الكائنات العالمية الفائقة مثل $_GET
و $_POST
و $_COOKIE
و $_SERVER
في الداخل. بالنسبة لأي متغير آخر من النطاق الأصلي، تحتاج إلى توفير نسخة بشكل صريح بالداخل عن طريق إضافة عبارة use
بعد قائمة المعلمات.
للتحقق من البريد الإلكتروني، يجب عليك إنشاء عنوان URL باستخدام المحدد والرمز المميز وإرساله إلى المستخدم، على سبيل المثال:
$ url = ' https://www.example.com/verify_email?selector= ' . urlencode ( $ selector ) . ' &token= ' . urlencode ( $ token );
ملحوظة: عند إرسال بريد إلكتروني إلى المستخدم، يرجى ملاحظة أن اسم المستخدم (الاختياري)، في هذه المرحلة، لم يتم تأكيد قبوله لمالك عنوان البريد الإلكتروني (الجديد) بعد. يمكن أن تحتوي على لغة مسيئة أو مضللة اختارها شخص ليس المالك الفعلي للعنوان.
بعد تقديم طلب تغيير عنوان البريد الإلكتروني، أو حتى أفضل، بعد تأكيد التغيير من قبل المستخدم، يجب عليك إرسال بريد إلكتروني إلى عنوان البريد الإلكتروني السابق لحسابه كإشعار خارج النطاق لإعلام مالك الحساب بذلك هذا التغيير الحاسم.
ملاحظة: تسري التغييرات التي يتم إجراؤها على عنوان البريد الإلكتروني للمستخدم في الجلسة المحلية على الفور، كما هو متوقع. في الجلسات الأخرى (على سبيل المثال على الأجهزة الأخرى)، قد تحتاج التغييرات إلى ما يصل إلى خمس دقائق حتى تصبح نافذة المفعول. يؤدي هذا إلى زيادة الأداء وعادةً لا يشكل أي مشكلة. إذا كنت تريد تغيير هذا السلوك، فما عليك سوى تقليل (أو ربما زيادة) القيمة التي تمررها إلى مُنشئ Auth
كوسيط اسمه $sessionResyncInterval
.
إذا تعذر تسليم طلب تأكيد سابق إلى المستخدم، أو إذا فاته المستخدم هذا الطلب، أو إذا كان لا يريد الانتظار لفترة أطول، فيمكنك إعادة إرسال طلب سابق مثل هذا:
try {
$ auth -> resendConfirmationForEmail ( $ _POST [ ' email ' ], function ( $ selector , $ token ) {
echo ' Send ' . $ selector . ' and ' . $ token . ' to the user (e.g. via email) ' ;
echo ' For emails, consider using the mail(...) function, Symfony Mailer, Swiftmailer, PHPMailer, etc. ' ;
echo ' For SMS, consider using a third-party service and a compatible SDK ' ;
});
echo ' The user may now respond to the confirmation request (usually by clicking a link) ' ;
}
catch ( Delight Auth ConfirmationRequestNotFound $ e ) {
die ( ' No earlier request found that could be re-sent ' );
}
catch ( Delight Auth TooManyRequestsException $ e ) {
die ( ' There have been too many requests -- try again later ' );
}
إذا كنت تريد تحديد المستخدم من خلال معرفه بدلاً من عنوان بريده الإلكتروني، فمن الممكن أيضًا:
try {
$ auth -> resendConfirmationForUserId ( $ _POST [ ' userId ' ], function ( $ selector , $ token ) {
echo ' Send ' . $ selector . ' and ' . $ token . ' to the user (e.g. via email) ' ;
echo ' For emails, consider using the mail(...) function, Symfony Mailer, Swiftmailer, PHPMailer, etc. ' ;
echo ' For SMS, consider using a third-party service and a compatible SDK ' ;
});
echo ' The user may now respond to the confirmation request (usually by clicking a link) ' ;
}
catch ( Delight Auth ConfirmationRequestNotFound $ e ) {
die ( ' No earlier request found that could be re-sent ' );
}
catch ( Delight Auth TooManyRequestsException $ e ) {
die ( ' There have been too many requests -- try again later ' );
}
ملحوظة: وظيفة رد الاتصال المجهول هي وظيفة إغلاق. وبالتالي، بالإضافة إلى المعلمات الخاصة به، لا تتوفر سوى الكائنات العالمية الفائقة مثل $_GET
و $_POST
و $_COOKIE
و $_SERVER
في الداخل. بالنسبة لأي متغير آخر من النطاق الأصلي، تحتاج إلى توفير نسخة بشكل صريح بالداخل عن طريق إضافة عبارة use
بعد قائمة المعلمات.
عادةً، يجب عليك إنشاء عنوان URL باستخدام المحدد والرمز المميز وإرساله إلى المستخدم، على سبيل المثال كما يلي:
$ url = ' https://www.example.com/verify_email?selector= ' . urlencode ( $ selector ) . ' &token= ' . urlencode ( $ token );
ملحوظة: عند إرسال بريد إلكتروني إلى المستخدم، يرجى ملاحظة أن اسم المستخدم (الاختياري)، في هذه المرحلة، لم يتم تأكيد قبوله لمالك عنوان البريد الإلكتروني (الجديد) بعد. يمكن أن تحتوي على لغة مسيئة أو مضللة اختارها شخص ليس المالك الفعلي للعنوان.
$ auth -> logOut ();
// or
try {
$ auth -> logOutEverywhereElse ();
}
catch ( Delight Auth NotLoggedInException $ e ) {
die ( ' Not logged in ' );
}
// or
try {
$ auth -> logOutEverywhere ();
}
catch ( Delight Auth NotLoggedInException $ e ) {
die ( ' Not logged in ' );
}
بالإضافة إلى ذلك، إذا قمت بتخزين معلومات مخصصة في الجلسة أيضًا، وإذا كنت تريد حذف هذه المعلومات، فيمكنك تدمير الجلسة بأكملها عن طريق استدعاء طريقة ثانية:
$ auth -> destroySession ();
ملاحظة: تسري عمليات تسجيل الخروج العامة في الجلسة المحلية على الفور، كما هو متوقع. في الجلسات الأخرى (على سبيل المثال على الأجهزة الأخرى)، قد تحتاج التغييرات إلى ما يصل إلى خمس دقائق حتى تصبح نافذة المفعول. يؤدي هذا إلى زيادة الأداء وعادةً لا يشكل أي مشكلة. إذا كنت تريد تغيير هذا السلوك، فما عليك سوى تقليل (أو ربما زيادة) القيمة التي تمررها إلى مُنشئ Auth
كوسيط اسمه $sessionResyncInterval
.
if ( $ auth -> isLoggedIn ()) {
echo ' User is signed in ' ;
}
else {
echo ' User is not signed in yet ' ;
}
الاختصار/الاسم المستعار لهذه الطريقة هو $auth->check()
.
$ id = $ auth -> getUserId ();
إذا لم يكن المستخدم قد قام بتسجيل الدخول حاليًا، فسيُرجع هذا null
.
الاختصار/الاسم المستعار لهذه الطريقة هو $auth->id()
.
$ email = $ auth -> getEmail ();
إذا لم يكن المستخدم قد قام بتسجيل الدخول حاليًا، فسيُرجع هذا null
.
$ username = $ auth -> getUsername ();
تذكر أن أسماء المستخدمين اختيارية ولا يوجد سوى اسم مستخدم إذا قمت بتقديمه أثناء التسجيل.
إذا لم يكن المستخدم قد قام بتسجيل الدخول حاليًا، فسيُرجع هذا null
.
if ( $ auth -> isNormal ()) {
echo ' User is in default state ' ;
}
if ( $ auth -> isArchived ()) {
echo ' User has been archived ' ;
}
if ( $ auth -> isBanned ()) {
echo ' User has been banned ' ;
}
if ( $ auth -> isLocked ()) {
echo ' User has been locked ' ;
}
if ( $ auth -> isPendingReview ()) {
echo ' User is pending review ' ;
}
if ( $ auth -> isSuspended ()) {
echo ' User has been suspended ' ;
}
if ( $ auth -> isRemembered ()) {
echo ' User did not sign in but was logged in through their long-lived cookie ' ;
}
else {
echo ' User signed in manually ' ;
}
إذا لم يكن المستخدم قد قام بتسجيل الدخول حاليًا، فسيُرجع هذا null
.
$ ip = $ auth -> getIpAddress ();
من أجل الحفاظ على ملاءمة هذه المكتبة لجميع الأغراض بالإضافة إلى إمكانية إعادة استخدامها بالكامل، فهي لا تأتي مع أعمدة مجمعة إضافية لمعلومات المستخدم. لكن ليس عليك الاستغناء عن معلومات المستخدم الإضافية بالطبع:
فيما يلي كيفية استخدام هذه المكتبة مع الجداول الخاصة بك للحصول على معلومات المستخدم المخصصة بطريقة قابلة للصيانة وإعادة الاستخدام:
قم بإضافة أي عدد من جداول قاعدة البيانات المخصصة حيث تقوم بتخزين معلومات المستخدم المخصصة، على سبيل المثال جدول يسمى profiles
.
كلما قمت باستدعاء طريقة register
(التي تقوم بإرجاع معرف المستخدم الجديد)، قم بإضافة المنطق الخاص بك بعد ذلك والذي يملأ جداول قاعدة البيانات المخصصة الخاصة بك.
إذا كنت تحتاج إلى معلومات المستخدم المخصصة نادرًا، فيمكنك استردادها حسب الحاجة. ومع ذلك، إذا كنت في حاجة إليها بشكل متكرر، فمن المحتمل أن ترغب في إدراجها في بيانات الجلسة الخاصة بك. الطريقة التالية هي كيفية تحميل بياناتك والوصول إليها بطريقة موثوقة:
function getUserInfo ( Delight Auth Auth $ auth ) {
if (! $ auth -> isLoggedIn ()) {
return null ;
}
if (! isset ( $ _SESSION [ ' _internal_user_info ' ])) {
// TODO : load your custom user information and assign it to the session variable below
// $ _SESSION [ ' _internal_user_info' ] = ...
}
return $ _SESSION [ ' _internal_user_info ' ];
}
عندما تريد تأكيد هوية المستخدم مرة أخرى، على سبيل المثال قبل السماح للمستخدم بتنفيذ بعض الإجراءات "الخطيرة"، يجب عليك التحقق من كلمة المرور الخاصة به مرة أخرى للتأكد من أنه هو بالفعل الشخص الذي يدعيه.
على سبيل المثال، عندما يتم تذكر المستخدم بواسطة ملف تعريف ارتباط طويل الأمد، وبالتالي يُرجع Auth#isRemembered
true
، فهذا يعني أن المستخدم ربما لم يُدخل كلمة المرور الخاصة به لبعض الوقت بعد الآن. قد ترغب في إعادة تأكيد كلمة المرور الخاصة بهم في هذه الحالة.
try {
if ( $ auth -> reconfirmPassword ( $ _POST [ ' password ' ])) {
echo ' The user really seems to be who they claim to be ' ;
}
else {
echo ' We can ' t say if the user is who they claim to be ' ;
}
}
catch ( Delight Auth NotLoggedInException $ e ) {
die ( ' The user is not signed in ' );
}
catch ( Delight Auth TooManyRequestsException $ e ) {
die ( ' Too many requests ' );
}
يمكن أن يكون لكل مستخدم أي عدد من الأدوار، والتي يمكنك استخدامها لتنفيذ الترخيص وتحسين عناصر التحكم في الوصول الخاصة بك.
قد لا يكون للمستخدمين أي دور على الإطلاق (وهو ما يفعلونه افتراضيًا)، أو دور واحد فقط، أو أي مجموعة عشوائية من الأدوار.
if ( $ auth -> hasRole ( Delight Auth Role:: SUPER_MODERATOR )) {
echo ' The user is a super moderator ' ;
}
// or
if ( $ auth -> hasAnyRole ( Delight Auth Role:: DEVELOPER , Delight Auth Role:: MANAGER )) {
echo ' The user is either a developer, or a manager, or both ' ;
}
// or
if ( $ auth -> hasAllRoles ( Delight Auth Role:: DEVELOPER , Delight Auth Role:: MANAGER )) {
echo ' The user is both a developer and a manager ' ;
}
بينما تأخذ الطريقة hasRole
دورًا واحدًا فقط كوسيطة لها، يمكن للطريقتين hasAnyRole
و hasAllRoles
أن تأخذا أي عدد من الأدوار التي ترغب في التحقق منها.
وبدلاً من ذلك، يمكنك الحصول على قائمة بجميع الأدوار التي تم تعيينها للمستخدم:
$ auth -> getRoles ();
Delight Auth Role:: ADMIN ;
Delight Auth Role:: AUTHOR ;
Delight Auth Role:: COLLABORATOR ;
Delight Auth Role:: CONSULTANT ;
Delight Auth Role:: CONSUMER ;
Delight Auth Role:: CONTRIBUTOR ;
Delight Auth Role:: COORDINATOR ;
Delight Auth Role:: CREATOR ;
Delight Auth Role:: DEVELOPER ;
Delight Auth Role:: DIRECTOR ;
Delight Auth Role:: EDITOR ;
Delight Auth Role:: EMPLOYEE ;
Delight Auth Role:: MAINTAINER ;
Delight Auth Role:: MANAGER ;
Delight Auth Role:: MODERATOR ;
Delight Auth Role:: PUBLISHER ;
Delight Auth Role:: REVIEWER ;
Delight Auth Role:: SUBSCRIBER ;
Delight Auth Role:: SUPER_ADMIN ;
Delight Auth Role:: SUPER_EDITOR ;
Delight Auth Role:: SUPER_MODERATOR ;
Delight Auth Role:: TRANSLATOR ;
يمكنك استخدام أي من هذه الأدوار وتجاهل تلك التي لا تحتاج إليها. يمكن أيضًا استرداد القائمة أعلاه برمجيًا، بأحد التنسيقات الثلاثة:
Delight Auth Role:: getMap ();
// or
Delight Auth Role:: getNames ();
// or
Delight Auth Role:: getValues ();
يتم ترميز أذونات كل مستخدم بالطريقة التي يتم بها تحديد متطلبات الدور في قاعدة التعليمات البرمجية الخاصة بك. إذا تم تقييم هذه المتطلبات باستخدام مجموعة أدوار مستخدم معين، فستكون النتيجة هي الأذونات المحددة ضمنيًا.
بالنسبة للمشاريع الأكبر حجمًا، يوصى غالبًا بالحفاظ على تعريف الأذونات في مكان واحد. وبعد ذلك، لا تقوم بالتحقق من الأدوار في منطق عملك، ولكنك تتحقق من الأذونات الفردية . ويمكنك تنفيذ هذا المفهوم على النحو التالي:
function canEditArticle ( Delight Auth Auth $ auth ) {
return $ auth -> hasAnyRole (
Delight Auth Role:: MODERATOR ,
Delight Auth Role:: SUPER_MODERATOR ,
Delight Auth Role:: ADMIN ,
Delight Auth Role:: SUPER_ADMIN
);
}
// . . .
if ( canEditArticle ( $ auth )) {
echo ' The user can edit articles here ' ;
}
// . . .
if ( canEditArticle ( $ auth )) {
echo ' ... and here ' ;
}
// . . .
if ( canEditArticle ( $ auth )) {
echo ' ... and here ' ;
}
كما ترون، يتم تخزين الإذن الخاص بما إذا كان يمكن لمستخدم معين تحرير مقالة في موقع مركزي. هذا التنفيذ له ميزتان رئيسيتان:
إذا كنت تريد معرفة المستخدمين الذين يمكنهم تحرير المقالات، فلن يتعين عليك التحقق من منطق عملك في أماكن مختلفة، ولكن كل ما عليك فعله هو البحث عن المكان الذي تم فيه تحديد الإذن المحدد. وإذا كنت تريد تغيير من يمكنه تحرير مقال، فما عليك سوى القيام بذلك في مكان واحد أيضًا، وليس في قاعدة التعليمات البرمجية بأكملها.
ولكن هذا يأتي أيضًا مع زيادة طفيفة في النفقات العامة عند تنفيذ قيود الوصول لأول مرة، وهو ما قد يكون أو لا يستحق ذلك لمشروعك.
إذا كانت أسماء الأدوار المضمنة لا تناسبك، فيمكنك استخدام الاسم المستعار لأي عدد من الأدوار باستخدام المعرفات الخاصة بك، على سبيل المثال كما يلي:
namespace My Namespace ;
final class MyRole {
const CUSTOMER_SERVICE_AGENT = Delight Auth Role:: REVIEWER ;
const FINANCIAL_DIRECTOR = Delight Auth Role:: COORDINATOR ;
private function __construct () {}
}
المثال أعلاه سيسمح لك باستخدام
My Namespace MyRole:: CUSTOMER_SERVICE_AGENT ;
// and
My Namespace MyRole:: FINANCIAL_DIRECTOR ;
بدلاً من
Delight Auth Role:: REVIEWER ;
// and
Delight Auth Role:: COORDINATOR ;
فقط تذكر عدم تسمية دور واحد مدرج بأسماء مستعارة لأدوار متعددة بأسماء مخصصة.
في حين أن إعادة تعيين كلمة المرور عبر البريد الإلكتروني هي ميزة مريحة يجدها معظم المستخدمين مفيدة من وقت لآخر، فإن توفر هذه الميزة يعني أن الحسابات في خدمتك تكون آمنة فقط مثل حساب البريد الإلكتروني المرتبط بالمستخدم.
يمكنك تزويد المستخدمين المهتمين بالأمان (وذوي الخبرة) بإمكانية تعطيل إعادة تعيين كلمة المرور لحساباتهم (وتمكينهم مرة أخرى لاحقًا) لتعزيز الأمان:
try {
if ( $ auth -> reconfirmPassword ( $ _POST [ ' password ' ])) {
$ auth -> setPasswordResetEnabled ( $ _POST [ ' enabled ' ] == 1 );
echo ' The setting has been changed ' ;
}
else {
echo ' We can ' t say if the user is who they claim to be ' ;
}
}
catch ( Delight Auth NotLoggedInException $ e ) {
die ( ' The user is not signed in ' );
}
catch ( Delight Auth TooManyRequestsException $ e ) {
die ( ' Too many requests ' );
}
للتحقق من القيمة الحالية لهذا الإعداد، استخدم القيمة المرجعة من
$ auth -> isPasswordResetEnabled ();
للخيار الافتراضي الصحيح في واجهة المستخدم الخاصة بك. لا تحتاج إلى التحقق من هذه القيمة لمعرفة القيود المفروضة على الميزة، والتي يتم فرضها تلقائيًا.
جميع الطرق التي توفرها هذه المكتبة محمية تلقائيًا ضد الأعداد الزائدة من الطلبات المقدمة من العملاء. إذا دعت الحاجة، يمكنك (مؤقتًا) تعطيل هذه الحماية باستخدام المعلمة $throttling
التي تم تمريرها إلى المُنشئ.
إذا كنت ترغب في تقييد الميزات أو الطرق الخارجية أو تحديد المعدل أيضًا، على سبيل المثال، تلك الموجودة في التعليمات البرمجية الخاصة بك، فيمكنك الاستفادة من طريقة المساعد المضمنة للتقييد وتحديد المعدل:
try {
// throttle the specified resource or feature to * 3 * requests per * 60 * seconds
$ auth -> throttle ([ ' my-resource-name ' ], 3 , 60 );
echo ' Do something with the resource or feature ' ;
}
catch ( Delight Auth TooManyRequestsException $ e ) {
// operation cancelled
http_response_code ( 429 );
exit ;
}
إذا كانت حماية المورد أو الميزة يجب أن تعتمد بالإضافة إلى ذلك على سمة أخرى، على سبيل المثال، لتتبع شيء ما بشكل منفصل لكل عنوان IP، فما عليك سوى إضافة المزيد من البيانات إلى وصف المورد، مثل:
[ ' my-resource-name ' , $ _SERVER [ ' REMOTE_ADDR ' ] ]
// instead of
// [ ' my-resource-name' ]
من الممكن السماح بتدفقات قصيرة من النشاط أثناء ذروة الطلب عن طريق تحديد عامل الاندفاع باعتباره الوسيط الرابع. فالقيمة 5
، على سبيل المثال، من شأنها أن تسمح بدفعات مؤقتة من النشاط خمسة أضعاف، مقارنة بالمستوى المقبول عمومًا.
في بعض الحالات، قد ترغب فقط في محاكاة التقييد أو تحديد المعدل. يتيح لك هذا التحقق مما إذا كان الإجراء مسموحًا به دون تعديل أداة تعقب النشاط فعليًا. وللقيام بذلك، ما عليك سوى تمرير true
باعتبارها الوسيطة الخامسة.
ملاحظة: عند تعطيل التقييد على المثيل (باستخدام المعلمة $throttling
التي تم تمريرها إلى المُنشئ)، يؤدي ذلك إلى إيقاف تشغيل كل من الحماية الداخلية التلقائية وتأثير أي استدعاءات لـ Auth#throttle
في كود التطبيق الخاص بك - ما لم تقم أيضًا بتعيين معلمة $force
اختيارية إلى true
في استدعاءات Auth#throttle
محددة.
الواجهة الإدارية متاحة عبر $auth->admin()
. يمكنك استدعاء طرق مختلفة على هذه الواجهة، كما هو موثق أدناه.
لا تنس تنفيذ التحكم الآمن في الوصول قبل تعريض الوصول إلى هذه الواجهة. على سبيل المثال، يمكنك توفير الوصول إلى هذه الواجهة للمستخدمين الذين قاموا بتسجيل الدخول باستخدام دور المسؤول فقط، أو استخدام الواجهة في البرامج النصية الخاصة فقط.
try {
$ userId = $ auth -> admin ()-> createUser ( $ _POST [ ' email ' ], $ _POST [ ' password ' ], $ _POST [ ' username ' ]);
echo ' We have signed up a new user with the ID ' . $ userId ;
}
catch ( Delight Auth InvalidEmailException $ e ) {
die ( ' Invalid email address ' );
}
catch ( Delight Auth InvalidPasswordException $ e ) {
die ( ' Invalid password ' );
}
catch ( Delight Auth UserAlreadyExistsException $ e ) {
die ( ' User already exists ' );
}
اسم المستخدم في المعلمة الثالثة اختياري. يمكنك تمرير null
هناك إذا كنت لا ترغب في إدارة أسماء المستخدمين.
إذا كنت تريد فرض أسماء مستخدمين فريدة، من ناحية أخرى، ما عليك سوى استدعاء createUserWithUniqueUsername
بدلاً من createUser
، وكن مستعدًا لالتقاط DuplicateUsernameException
.
حذف المستخدمين حسب معرفهم:
try {
$ auth -> admin ()-> deleteUserById ( $ _POST [ ' id ' ]);
}
catch ( Delight Auth UnknownIdException $ e ) {
die ( ' Unknown ID ' );
}
حذف المستخدمين حسب عنوان بريدهم الإلكتروني:
try {
$ auth -> admin ()-> deleteUserByEmail ( $ _POST [ ' email ' ]);
}
catch ( Delight Auth InvalidEmailException $ e ) {
die ( ' Unknown email address ' );
}
حذف المستخدمين حسب اسم المستخدم الخاص بهم:
try {
$ auth -> admin ()-> deleteUserByUsername ( $ _POST [ ' username ' ]);
}
catch ( Delight Auth UnknownUsernameException $ e ) {
die ( ' Unknown username ' );
}
catch ( Delight Auth AmbiguousUsernameException $ e ) {
die ( ' Ambiguous username ' );
}
عند جلب قائمة بجميع المستخدمين، تختلف المتطلبات بشكل كبير بين المشاريع وحالات الاستخدام، ويكون التخصيص أمرًا شائعًا. على سبيل المثال، قد ترغب في جلب أعمدة مختلفة، والانضمام إلى الجداول ذات الصلة، والتصفية حسب معايير معينة، وتغيير كيفية فرز النتائج (في اتجاهات مختلفة)، والحد من عدد النتائج (مع توفير الإزاحة).
ولهذا السبب، من الأسهل استخدام استعلام SQL مخصص واحد. ابدأ بما يلي:
SELECT id, email, username, status, verified, roles_mask, registered, last_login FROM users;
try {
$ auth -> admin ()-> addRoleForUserById ( $ userId , Delight Auth Role:: ADMIN );
}
catch ( Delight Auth UnknownIdException $ e ) {
die ( ' Unknown user ID ' );
}
// or
try {
$ auth -> admin ()-> addRoleForUserByEmail ( $ userEmail , Delight Auth Role:: ADMIN );
}
catch ( Delight Auth InvalidEmailException $ e ) {
die ( ' Unknown email address ' );
}
// or
try {
$ auth -> admin ()-> addRoleForUserByUsername ( $ username , Delight Auth Role:: ADMIN );
}
catch ( Delight Auth UnknownUsernameException $ e ) {
die ( ' Unknown username ' );
}
catch ( Delight Auth AmbiguousUsernameException $ e ) {
die ( ' Ambiguous username ' );
}
ملاحظة: قد تحتاج التغييرات التي يتم إجراؤها على مجموعة أدوار المستخدم إلى ما يصل إلى خمس دقائق حتى تدخل حيز التنفيذ. يؤدي هذا إلى زيادة الأداء وعادةً لا يشكل أي مشكلة. إذا كنت تريد تغيير هذا السلوك، فما عليك سوى تقليل (أو ربما زيادة) القيمة التي تمررها إلى مُنشئ Auth
كوسيط اسمه $sessionResyncInterval
.
try {
$ auth -> admin ()-> removeRoleForUserById ( $ userId , Delight Auth Role:: ADMIN );
}
catch ( Delight Auth UnknownIdException $ e ) {
die ( ' Unknown user ID ' );
}
// or
try {
$ auth -> admin ()-> removeRoleForUserByEmail ( $ userEmail , Delight Auth Role:: ADMIN );
}
catch ( Delight Auth InvalidEmailException $ e ) {
die ( ' Unknown email address ' );
}
// or
try {
$ auth -> admin ()-> removeRoleForUserByUsername ( $ username , Delight Auth Role:: ADMIN );
}
catch ( Delight Auth UnknownUsernameException $ e ) {
die ( ' Unknown username ' );
}
catch ( Delight Auth AmbiguousUsernameException $ e ) {
die ( ' Ambiguous username ' );
}
ملاحظة: قد تحتاج التغييرات التي يتم إجراؤها على مجموعة أدوار المستخدم إلى ما يصل إلى خمس دقائق حتى تدخل حيز التنفيذ. يؤدي هذا إلى زيادة الأداء وعادةً لا يشكل أي مشكلة. إذا كنت تريد تغيير هذا السلوك، فما عليك سوى تقليل (أو ربما زيادة) القيمة التي تمررها إلى مُنشئ Auth
كوسيط اسمه $sessionResyncInterval
.
try {
if ( $ auth -> admin ()-> doesUserHaveRole ( $ userId , Delight Auth Role:: ADMIN )) {
echo ' The specified user is an administrator ' ;
}
else {
echo ' The specified user is not an administrator ' ;
}
}
catch ( Delight Auth UnknownIdException $ e ) {
die ( ' Unknown user ID ' );
}
وبدلاً من ذلك، يمكنك الحصول على قائمة بجميع الأدوار التي تم تعيينها للمستخدم:
$ auth -> admin ()-> getRolesForUserById ( $ userId );
try {
$ auth -> admin ()-> logInAsUserById ( $ _POST [ ' id ' ]);
}
catch ( Delight Auth UnknownIdException $ e ) {
die ( ' Unknown ID ' );
}
catch ( Delight Auth EmailNotVerifiedException $ e ) {
die ( ' Email address not verified ' );
}
// or
try {
$ auth -> admin ()-> logInAsUserByEmail ( $ _POST [ ' email ' ]);
}
catch ( Delight Auth InvalidEmailException $ e ) {
die ( ' Unknown email address ' );
}
catch ( Delight Auth EmailNotVerifiedException $ e ) {
die ( ' Email address not verified ' );
}
// or
try {
$ auth -> admin ()-> logInAsUserByUsername ( $ _POST [ ' username ' ]);
}
catch ( Delight Auth UnknownUsernameException $ e ) {
die ( ' Unknown username ' );
}
catch ( Delight Auth AmbiguousUsernameException $ e ) {
die ( ' Ambiguous username ' );
}
catch ( Delight Auth EmailNotVerifiedException $ e ) {
die ( ' Email address not verified ' );
}
try {
$ auth -> admin ()-> changePasswordForUserById ( $ _POST [ ' id ' ], $ _POST [ ' newPassword ' ]);
}
catch ( Delight Auth UnknownIdException $ e ) {
die ( ' Unknown ID ' );
}
catch ( Delight Auth InvalidPasswordException $ e ) {
die ( ' Invalid password ' );
}
// or
try {
$ auth -> admin ()-> changePasswordForUserByUsername ( $ _POST [ ' username ' ], $ _POST [ ' newPassword ' ]);
}
catch ( Delight Auth UnknownUsernameException $ e ) {
die ( ' Unknown username ' );
}
catch ( Delight Auth AmbiguousUsernameException $ e ) {
die ( ' Ambiguous username ' );
}
catch ( Delight Auth InvalidPasswordException $ e ) {
die ( ' Invalid password ' );
}
تستخدم هذه المكتبة ملفي تعريف ارتباط للحفاظ على حالة العميل: الأول، والذي يمكنك استرجاع اسمه باستخدامه
session_name ();
هو ملف تعريف الارتباط للجلسة العامة (الإلزامية). يتم استخدام ملف تعريف الارتباط الثاني (الاختياري) فقط لتسجيلات الدخول المستمرة ويمكن استرجاع اسمه على النحو التالي:
Delight Auth Auth:: createRememberCookieName ();
يمكنك إعادة تسمية ملف تعريف ارتباط الجلسة الذي تستخدمه هذه المكتبة من خلال إحدى الوسائل التالية، حسب ترتيب التوصية:
في إعدادات PHP ( php.ini
)، ابحث عن السطر الذي يحتوي على التوجيه session.name
وقم بتغيير قيمته إلى شيء مثل session_v1
، كما في:
session.name = session_v1
في أقرب وقت ممكن في التطبيق الخاص بك، وقبل إنشاء مثيل Auth
، اتصل بـ ini_set
لتغيير session.name
إلى شيء مثل session_v1
، كما في:
ini_set ( ' session.name ' , ' session_v1 ' );
لكي ينجح هذا الأمر، يجب ضبط session.auto_start
على 0
في إعدادات PHP ( php.ini
).
في أقرب وقت ممكن في التطبيق الخاص بك، وقبل إنشاء مثيل Auth
، اتصل بـ session_name
باستخدام وسيطة مثل session_v1
، كما في:
session_name ( ' session_v1 ' );
لكي ينجح هذا الأمر، يجب ضبط session.auto_start
على 0
في إعدادات PHP ( php.ini
).
سيتم أيضًا تغيير اسم ملف تعريف الارتباط لعمليات تسجيل الدخول المستمرة - تلقائيًا - بعد تغيير اسم ملف تعريف الارتباط للجلسة.
تتحكم سمة domain
ملف تعريف الارتباط في المجال (والنطاقات الفرعية) الذي سيكون ملف تعريف الارتباط صالحًا له، وبالتالي حيث ستكون جلسة المستخدم وحالة المصادقة متاحة.
الإعداد الافتراضي الموصى به هو سلسلة فارغة، مما يعني أن ملف تعريف الارتباط سيكون صالحًا فقط للمضيف الحالي بالضبط ، باستثناء أي نطاقات فرعية قد تكون موجودة. يجب عليك استخدام قيمة مختلفة فقط إذا كنت بحاجة إلى مشاركة ملفات تعريف الارتباط بين نطاقات فرعية مختلفة. في كثير من الأحيان، سوف ترغب في مشاركة ملفات تعريف الارتباط بين النطاق المجرد والنطاق الفرعي www
، ولكن قد ترغب أيضًا في مشاركتها بين أي مجموعة أخرى من النطاقات الفرعية.
مهما كانت مجموعة النطاقات الفرعية التي تختارها، يجب عليك تعيين سمة ملف تعريف الارتباط على اسم النطاق الأكثر تحديدًا والذي لا يزال يتضمن جميع النطاقات الفرعية المطلوبة. على سبيل المثال، لمشاركة ملفات تعريف الارتباط بين example.com
و www.example.com
، يمكنك تعيين السمة إلى example.com
. ولكن إذا أردت مشاركة ملفات تعريف الارتباط بين sub1.app.example.com
و sub2.app.example.com
، فيجب عليك تعيين السمة على app.example.com
. أي اسم نطاق محدد بشكل صريح سيتضمن دائمًا جميع النطاقات الفرعية التي قد تكون موجودة.
يمكنك تغيير السمة من خلال إحدى الوسائل التالية، حسب ترتيب التوصية:
في تكوين PHP ( php.ini
)، ابحث عن السطر الذي يحتوي على التوجيه session.cookie_domain
وقم بتغيير قيمته حسب الرغبة، على سبيل المثال:
session.cookie_domain = example.com
في أقرب وقت ممكن في التطبيق الخاص بك، وقبل إنشاء مثيل Auth
، اتصل بـ ini_set
لتغيير قيمة توجيه session.cookie_domain
حسب الرغبة، على سبيل المثال:
ini_set ( ' session.cookie_domain ' , ' example.com ' );
لكي ينجح هذا الأمر، يجب ضبط session.auto_start
على 0
في إعدادات PHP ( php.ini
).
تتحكم سمة path
ملف تعريف الارتباط في الدلائل (والدلائل الفرعية) التي سيكون ملف تعريف الارتباط صالحًا لها، وبالتالي حيث ستكون جلسة المستخدم وحالة المصادقة متاحة.
في معظم الحالات، ستحتاج إلى إتاحة ملفات تعريف الارتباط لجميع المسارات، أي أي دليل وملف، بدءًا من الدليل الجذر. هذا هو ما تفعله قيمة /
للسمة، وهي أيضًا القيمة الافتراضية الموصى بها. يجب عليك فقط تغيير هذه السمة إلى قيمة مختلفة، على سبيل المثال /path/to/subfolder
، إذا كنت تريد تقييد الأدلة التي ستكون ملفات تعريف الارتباط الخاصة بك متاحة فيها، على سبيل المثال، لاستضافة تطبيقات متعددة جنبًا إلى جنب، في أدلة مختلفة، ضمن نفس اسم المجال.
يمكنك تغيير السمة من خلال إحدى الوسائل التالية، حسب ترتيب التوصية:
في تكوين PHP ( php.ini
)، ابحث عن السطر الذي يحتوي على التوجيه session.cookie_path
وقم بتغيير قيمته حسب الرغبة، على سبيل المثال:
session.cookie_path = /
في أقرب وقت ممكن في التطبيق الخاص بك، وقبل إنشاء مثيل Auth
، اتصل بـ ini_set
لتغيير قيمة توجيه session.cookie_path
حسب الرغبة، على سبيل المثال:
ini_set ( ' session.cookie_path ' , ' / ' );
لكي ينجح هذا الأمر، يجب ضبط session.auto_start
على 0
في إعدادات PHP ( php.ini
).
باستخدام السمة httponly
، يمكنك التحكم فيما إذا كانت البرامج النصية من جانب العميل، أي JavaScript، يجب أن تكون قادرة على الوصول إلى ملفات تعريف الارتباط الخاصة بك أم لا. لأسباب أمنية، من الأفضل رفض وصول البرنامج النصي إلى ملفات تعريف الارتباط الخاصة بك، مما يقلل من الضرر الذي يمكن أن تحدثه هجمات XSS الناجحة ضد تطبيقك، على سبيل المثال.
وبالتالي، يجب عليك دائمًا تعيين httponly
على 1
، باستثناء الحالات النادرة التي تحتاج فيها حقًا إلى الوصول إلى ملفات تعريف الارتباط الخاصة بك من JavaScript ولا يمكنك العثور على أي حل أفضل. في تلك الحالات، قم بتعيين السمة على 0
، ولكن كن على دراية بالعواقب.
يمكنك تغيير السمة من خلال إحدى الوسائل التالية، حسب ترتيب التوصية:
في تكوين PHP ( php.ini
)، ابحث عن السطر الذي يحتوي على التوجيه session.cookie_httponly
وقم بتغيير قيمته حسب الرغبة، على سبيل المثال:
session.cookie_httponly = 1
في أقرب وقت ممكن في التطبيق الخاص بك، وقبل إنشاء مثيل Auth
، اتصل بـ ini_set
لتغيير قيمة توجيه session.cookie_httponly
حسب الرغبة، على سبيل المثال:
ini_set ( ' session.cookie_httponly ' , 1 );
لكي ينجح هذا الأمر، يجب ضبط session.auto_start
على 0
في إعدادات PHP ( php.ini
).
باستخدام السمة secure
، يمكنك التحكم في ما إذا كان يجب إرسال ملفات تعريف الارتباط عبر أي اتصال، بما في ذلك HTTP العادي، أو ما إذا كان يجب أن يكون الاتصال الآمن، أي HTTPS (مع SSL/TLS)، مطلوبًا. يمكن اختيار الوضع السابق (الأقل أمانًا) عن طريق تعيين السمة على 0
، ويمكن اختيار الوضع الأخير (الأكثر أمانًا) عن طريق تعيين السمة على 1
.
من الواضح أن هذا يعتمد فقط على ما إذا كنت قادرًا على خدمة جميع الصفحات حصريًا عبر HTTPS. إذا أمكن، يجب عليك تعيين السمة على 1
وربما دمجها مع عمليات إعادة توجيه HTTP إلى البروتوكول الآمن وأمان النقل الصارم لـ HTTP (HSTS). بخلاف ذلك، قد تضطر إلى الاحتفاظ بالسمة المعينة على 0
.
يمكنك تغيير السمة من خلال إحدى الوسائل التالية، حسب ترتيب التوصية:
في تكوين PHP ( php.ini
)، ابحث عن السطر الذي يحتوي على التوجيه session.cookie_secure
وقم بتغيير قيمته حسب الرغبة، على سبيل المثال:
session.cookie_secure = 1
في أقرب وقت ممكن في التطبيق الخاص بك، وقبل إنشاء مثيل Auth
، اتصل بـ ini_set
لتغيير قيمة التوجيه session.cookie_secure
حسب الرغبة، على سبيل المثال:
ini_set ( ' session.cookie_secure ' , 1 );
لكي ينجح هذا الأمر، يجب ضبط session.auto_start
على 0
في إعدادات PHP ( php.ini
).
$ length = 24 ;
$ randomStr = Delight Auth Auth:: createRandomString ( $ length );
$ uuid = Delight Auth Auth:: createUuid ();
للحصول على معلومات تفصيلية حول كيفية قراءة بيانات الجلسة وكتابتها بسهولة، يرجى الرجوع إلى وثائق مكتبة الجلسة، والتي يتم تضمينها افتراضيًا.
تتم تجزئة أي كلمة مرور أو رمز مصادقة مميز تلقائيًا باستخدام وظيفة "bcrypt"، التي تعتمد على تشفير "Blowfish" والتي (لا تزال) تعتبر واحدة من أقوى وظائف تجزئة كلمة المرور اليوم. يتم استخدام "bcrypt" مع 1024 تكرارًا، أي أن عامل "التكلفة" يساوي 10. ويتم تطبيق "ملح" عشوائي تلقائيًا أيضًا.
يمكنك التحقق من هذا التكوين من خلال النظر إلى التجزئات الموجودة في users
جدول قاعدة البيانات لديك. إذا كان ما ورد أعلاه صحيحًا في الإعداد، فيجب أن تبدأ جميع تجزئات كلمة المرور في جدول users
بالبادئة $2$10$
أو $2a$10$
أو $2y$10$
.
عندما يتم تقديم خوارزميات جديدة (مثل Argon2) في المستقبل، ستتولى هذه المكتبة تلقائيًا "ترقية" تجزئات كلمة المرور الحالية الخاصة بك عندما يقوم المستخدم بتسجيل الدخول أو تغيير كلمة المرور الخاصة به.
عادةً ما يكون فرض الحد الأدنى لطول كلمات المرور فكرة جيدة. بصرف النظر عن ذلك، قد ترغب في البحث عما إذا كانت كلمة المرور المحتملة موجودة في بعض القائمة السوداء، والتي يمكنك إدارتها في قاعدة بيانات أو في ملف، وذلك لمنع استخدام كلمات القاموس أو كلمات المرور شائعة الاستخدام في تطبيقك.
للسماح بأقصى قدر من المرونة وسهولة الاستخدام، تم تصميم هذه المكتبة بحيث لا تحتوي على أي عمليات تحقق إضافية لمتطلبات كلمة المرور نفسها، ولكنها بدلاً من ذلك تسمح لك بتغليف عمليات التحقق الخاصة بك حول الاستدعاءات ذات الصلة لطرق المكتبة. مثال:
function isPasswordAllowed ( $ password ) {
if ( strlen ( $ password ) < 8 ) {
return false ;
}
$ blacklist = [ ' password1 ' , ' 123456 ' , ' qwerty ' ];
if ( in_array ( $ password , $ blacklist )) {
return false ;
}
return true ;
}
if ( isPasswordAllowed ( $ password )) {
$ auth -> register ( $ email , $ password );
}
يمكنك محاولة تحميل هذه المكتبة أولاً، وإنشاء مثيل Auth
أولاً، قبل تحميل المكتبات الأخرى. بصرف النظر عن ذلك، ربما ليس هناك الكثير الذي يمكننا القيام به هنا.
إذا كنت تريد السماح للآخرين بتضمين موقعك في عنصر <frame>
أو <iframe>
أو <object>
أو <embed>
أو <applet>
، فيجب عليك تعطيل منع النقر الافتراضي:
header_remove ( ' X-Frame-Options ' );
تطرح هذه المكتبة نوعين من الاستثناءات للإشارة إلى المشكلات:
AuthException
وفئاته الفرعية عندما لا تكتمل الطريقة بنجاح. يجب عليك دائمًا اكتشاف هذه الاستثناءات لأنها تحمل استجابات الخطأ العادية التي يجب عليك الرد عليها.AuthError
وفئاته الفرعية عندما تكون هناك مشكلة داخلية أو لم يتم تثبيت المكتبة بشكل صحيح. يجب أن لا تلتقط هذه الاستثناءات. جميع المساهمات هي موضع ترحيب! إذا كنت ترغب في المساهمة ، فيرجى إنشاء مشكلة أولاً بحيث يمكن مناقشة الميزة أو المشكلات أو السؤال.
هذا المشروع مرخص بموجب شروط ترخيص معهد ماساتشوستس للتكنولوجيا.