PDA

View Full Version : سوال: همزمان لاگین نشدن دو شخص با یه نام کاربری



Tarragon
دوشنبه 25 اردیبهشت 1391, 19:52 عصر
سلام.
من دارم یه CMS می نویسم که بدونم چه قدر PHP بلدم و کجا ها مشکل دارم.
این CMS هم ثبت نام داره و هم ورود که با کوکی کار می کنه اما من کوکی هارو جوری ست کردم که هر دفعه از دیتابیس یوزر نیم و پسورد رو بخونه ببینه درسته یا نه حالا می خوام کاری کنم که با یک نام کاربری نشه همزمان دوبار وارد شد به معنی دیگه می خوام کاری کنم که وقتی یکی با یه یوزر آنلاینه یکی دیگه نتونه با همون یوزر وارد شه حالا شما بگید من چکار کنم؟

farhadfery
دوشنبه 25 اردیبهشت 1391, 22:53 عصر
من هم قبلا به دنبال این مسله بودم. اما بعد دیدم کار بیهوده ای هست. بیخیال شدم. شما الان با ie و firefox همزمان می تونید mail خودتون را باز کنید

eshpilen
دوشنبه 25 اردیبهشت 1391, 23:29 عصر
این سوال رو خیلی وقت پیش یکی در تالار دیگری پرسیده بود که بنده یک الگوریتمی پیشنهاد کرده بودم.
شما میتونی از این استفاده کنی که برای هر لاگین یک id خاص بذاری. احتمالا یک token رندوم.

کاربر لاگین میکنه، توکن x به لاگینش تعلق میگیره.
حالا اگر نظیر چنین شرایط رخ داد یعنی دو تا لاگین همزمان وجود داره:
x y x در یک فاصلهء زمانی کوتاه.
یعنی چی؟ یعنی درخواست با لاگین x در زمان t1 وارد میشه، در زمان t2 درخواست با لاگین y وارد میشه، در زمان t3 مجددا درخواست با لاگین x وارد میشه. خب اگر فاصلهء زمانی t1 تا t3 بقدر کافی کم باشه (مثلا یک ربع ساعت) معلوم میشه که اکانت مورد نظر بصورت همزمان داره توسط بیش از یک نفر استفاده میشه. البته اطمینان از این 100% نیست ولی 99% قضیه از این قراره.

پیاده سازی الگوریتم این سیستم البته یک مقدار ظریف و تخصصی باشه بنظرم. شاید هم بیشتر از یک مقدار!! بهرحال اینکه بنده گفتم کلیت الگوریتم و هستهء اونه بصورت کاملا خام و تئوریک.

ضمنا این الگوریتم فقط دسترسی همزمان رو کشف میکنه. یعنی هر دو نفر در یک فاصلهء زمانی نزدیک به هم در سایت کار کنن.

روش دیگر هم نمیدونم تا چه حدی شدنی و اصولیه، ولی شاید بشه بر اساس IP کار کرد. نه؟ مثلا هر IP که کاربر اخیرا باهاش در سایت بوده رو ذخیره کنیم و اگر IP عوض شد، لاگین کاربر رو باطل کنیم. اما این ممکنه یک مقدار دردسر برای کاربر ایجاد کنه و زیاد اصولی نباشه. چون ممکنه IP یک کاربر به دلایل مختلف تغییر کنه. ضمنا در شرایطی که یک IP به هر دلیلی بین چند نفر به اشتراک گذاشته شده باشه این سیستم نمیتونه از دسترسی همزمان جلوگیری کنه. البته شاید چنین شرایطی اصلا متداول و بنابراین مهم نباشه. معمولا در LAN ها یا اینترانت سازمانها ممکنه اینطور باشه (اشتراک آیپی)، ولی ممکنه جاهای دیگری به دلایل دیگر هم باشه.

djsaeedkhan
دوشنبه 25 اردیبهشت 1391, 23:39 عصر
سلام
خوب شما وقتی کاربر لوگین کرد یه فیلد رو 1 کن و وقتی لوگ آوت کرد 0 کن
وقتی خواست لوگین کنه ببین 1 هست یا 0
اگر 1 بود نزار لوگین کنه


شما الان با ie و firefox همزمان می تونید mail خودتون را باز کنید
برای میل مهم نیست که چند نفر باشن. ولی اگر شما با یاهو مسنجر لوگین کنی و بعد با مسنجر میل باز کنی میبینی که بهت اجازه نمیده

چیز خاصی نیست. مگر اینکه من متوجه منظور شما نشدم

farhadfery
دوشنبه 25 اردیبهشت 1391, 23:56 عصر
وب شما وقتی کاربر لوگین کرد یه فیلد رو 1 کن و وقتی لوگ آوت کرد 0 کن
وقتی خواست لوگین کنه ببین 1 هست یا 0
اگر 1 بود نزار لوگین کنه
اینها را داداش من قبلا فکر کردم. اگر وسط کار user. اتصالش با اینترنت قطع شد. دیگه هیچوقت نمی تونه لاگین کنه:چشمک: چون فیلد 1 هست

djsaeedkhan
دوشنبه 25 اردیبهشت 1391, 23:59 عصر
خوب قبلا درباره این هم صحبت شده بود
شما اگر از همین سایت لوگ آوت نکنی. بعد یه چند ساعت بری میگه آفلاینی. از کجا فهمیده؟؟؟:گیج:
شما کاربر رو تحت نظر می گیری دیگه وقتی دیدی آفلاین شده اون فیلد رو صفر می کنی. وقتی هم دوباره اومد میگی برو لوگین کن. تمام

Unique
سه شنبه 26 اردیبهشت 1391, 03:07 صبح
راستش اینکه نشه دو نفر در یک زمان با یک نام کاربری کار کنند اصلا سخت نیست و بهترین کار اینه که وقتی نفر دوم لاگین میکنه ! نفر اول را بندازین بیرون (یعنی هر جوری authentication ها را انجام میدین اولی را باطل کنین) اینجوری دو نفروشن میفهمن که نباید با هم استفاده کنند چون مثل توپ پینگ پنگ login/logout میشن و مقصر هم خود کسی هست که پسوردش را داده یک نفر دیگه ! در ضمن اگه معیارتون IP باشه اگه دو نفرشون توی یک شرکت و روی یک LAN و یک Gateway باشن اصلا نمیفهمین دو یا هزار نفر با هم استفاده میکنند و معیار باید یا session باشه یا خودتون cookie را ست کنین !

Tarragon
سه شنبه 26 اردیبهشت 1391, 08:03 صبح
عزیزان الان من درست نفهمیدم باید با کوکی ها طرف رو بندازم بیرون یا تو دیتابیس از 0 و 1 استفاده کنم یا .....
تشکر

eshpilen
سه شنبه 26 اردیبهشت 1391, 08:10 صبح
راستش اینکه نشه دو نفر در یک زمان با یک نام کاربری کار کنند اصلا سخت نیست و بهترین کار اینه که وقتی نفر دوم لاگین میکنه ! نفر اول را بندازین بیرون (یعنی هر جوری authentication ها را انجام میدین اولی را باطل کنین) اینجوری دو نفروشن میفهمن که نباید با هم استفاده کنند چون مثل توپ پینگ پنگ login/logout میشن و مقصر هم خود کسی هست که پسوردش را داده یک نفر دیگه ! در ضمن اگه معیارتون IP باشه اگه دو نفرشون توی یک شرکت و روی یک LAN و یک Gateway باشن اصلا نمیفهمین دو یا هزار نفر با هم استفاده میکنند و معیار باید یا session باشه یا خودتون cookie را ست کنین !
اتفاقا منم الان اومده بودم همین روش رو بگم.
چون در پروژهء خودم چنین حالتی داره. یعنی وقتی طرف لاگین میکنه کلید لاگین عوض میشه و بنابراین سیستمهای دیگری که قبلا لاگین بودن از لاگین خارج میشن. البته بنده این رو بخاطر مسائل امنیتی پیاده کردم و نه بخاطر جلوگیری از لاگین همزمان با توافق قبلی!!
ضمنا با کپی کردن مقدار کوکی احراز هویت میتونن این سیستم رو دور بزنن و بنابراین اگر بخوایم سیستم واقعا قوی و اصولی باشه احتمالا باید از یک سیستم ترکیبی استفاده کنیم (از اون الگوریتمی که قبلا گفته بودم هم استفاده بشه). ولی اگر قصد فقط در حدی هست که استفادهء کاربران عادی رو محدود بکنه و زیاد بحث امنیتی نیست خب همون روش عوض کردن کلید لاگین کفایت میکنه احتمالا.

Tarragon
سه شنبه 26 اردیبهشت 1391, 08:38 صبح
اقا می شه بیشتر در مورد authentication توضیح بدید.
یا یه کد بزارید که من استفاده authentication رو بفهمم.
ممنون

eshpilen
سه شنبه 26 اردیبهشت 1391, 10:11 صبح
اقا می شه بیشتر در مورد authentication توضیح بدید.
یا یه کد بزارید که من استفاده authentication رو بفهمم.
ممنون
authentication از نظر لغوی یعنی احراز و ثابت شدن. منظور ما همون احراز هویته که بخصوص در برنامه نویسی و بخصوص در برنامه نویسی وب معمولا به این معنا بکار میره.
سیستم احراز هویت هم میتونه به روشها و شکلهای مختلفی باشه.
فرضا من اومدم در پروژهء خودم برای هر کاربر که ثبت نام میکنه یک رشتهء رندوم در رکورد اکانت اون کاربر درج میکنم بنام کلید لاگین. هر بار که کاربر لاگین میکنه این کلید لاگین رو در یک کوکی در سمت کلاینت ذخیره میکنم. بعد برای احراز هویت کاربر کافیه چک کنیم که آیا کلید لاگین و userid موجود در کوکی با مقدار موجود در رکورد اکانت اون کاربر تطابق دارن یا خیر.
البته یکسری جزییات و محاسبه های رمزنگاری هم باید لحاظ بشه. مثلا رشتهء رندوم باید از چه کاراکترهایی و چه طولی تشکیل شده باشه. این محاسبه داره. باید تعداد حالتهای ممکن اون بقدر کافی زیاد باشه. حالا اینکه بقدر کافی چقدره، مثلا 2 به توان 128 بنظرم کاملا کافیه، اما من برای اطمینان در حد بین المللی (!) از 2 به توان 256 استفاده کردم که احتمالا لازم نبوده ولی خب ضرر یا هزینهء خاصی هم نداره.
همینطور مثلا حتی الامکان باید از ذخیرهء نام کاربری بصورت مستقیم در کوکی اجتناب کرد. بجاش میتونید userid عددی یا یه چیز دیگه ای رو ذخیره کنید.
ضمنا تولید این رشتهء رندوم باید توسط یک تابع رندوم امن مناسب برای رمزنگاری (CSPRNG) انجام بشه. فرضا استفاده از زمان و یا توابعی مثل mt_rand و اینطور چیزها، به تنهایی بقدر کافی امن نیست.

خب حالا فرض کنید شما هر بار که کاربر بصورت دستی لاگین میکنه بیاید و اول کلید لاگین اون کاربر رو در دیتابیس تغییر بدید و بعد کلید لاگین جدید رو در کوکی ذخیره کنید. نتیجهء این کار این میشه که اگر کاربر قبلا روی سیستم دیگری لاگین بوده حالا کلید لاگین اون سیستم باطل میشه و دیگه با رکورد دیتابیس مچ نمیکنه و بنابراین اون سیستم از لاگین خارج میشه.

به همین سادگی به همین خوشمزگی!!

Unique
سه شنبه 26 اردیبهشت 1391, 11:11 صبح
دوست عزیز authentication یعنی همون احراز هویت کاربر از طریق نام کاربری و کلمه عبور (ما فرنگی گفتیم ریا نشه)
شما از همون کوکی خودتون استفاده کنین و احتمال زیاد برای هر کسی که لاگین میکنه از طریق کوکی که برای شما ارسال میشه احراز هویت میکنید ! حالا اگه نفر دومی با همون نام کاربری لاگین کرد با استفاده از همون منطقی که برنامه را نوشتین کوکی کاربر اول را باطل کنین ! مثلا اگه شماره ردیف یا token توی کوکی ذخیره میکنید رکورد مربوطه را حذف کنید تا کاربر اول اتوماتیک logout بشه.
در مورد کد هم شرمنده اصلا وقتشو نه من دارم نه دوستان دیگه اگه سوال دیگه ای هست بپرسین هر کسی تونست کمک میکنه ، تا زمانی هم که دست به کار نشین نتیجه ای نمیگیرین !

Tarragon
سه شنبه 26 اردیبهشت 1391, 12:07 عصر
سلام.
نظرتون چیه که توی دیتابیس یه قسمت دیگه برای هر یوزر بسازم که توش موقع لوگین یه عدد random قرار بگیره و اگر کسی دوباره لوگین کرد این عدد دوباره بصورت random ست بشه و توی هر صفحه تست کنه ببینه عدد مربوطه درست هست یا نه ؟
راستی اینجوری فشاری به سرور نمی یاد؟

djsaeedkhan
سه شنبه 26 اردیبهشت 1391, 12:32 عصر
سلام.
نظرتون چیه که توی دیتابیس یه قسمت دیگه برای هر یوزر بسازم که توش موقع لوگین یه عدد random قرار بگیره و اگر کسی دوباره لوگین کرد این عدد دوباره بصورت random ست بشه و توی هر صفحه تست کنه ببینه عدد مربوطه درست هست یا نه ؟
راستی اینجوری فشاری به سرور نمی یاد؟

سلام
شما واقعا دارید لقمه رو دور سر می چرخونید

Tarragon
سه شنبه 26 اردیبهشت 1391, 12:56 عصر
شما راه حل بهتری سراغ دارید؟