تابع is_user_logged_in یکی از پایه‌ای‌ترین توابع وردپرس برای بررسی وضعیت ورود کاربر جاری است. این تابع یک مقدار بولی بازمی‌گرداند و در طراحی رفتارهای شرطی قالب، افزونه و REST API نقشی کلیدی دارد. تشخیص درست این وضعیت، پیش‌نیاز نمایش محتوای شخصی‌سازی‌شده و محافظت از بخش‌های حساس سایت است. اشتباهات رایجی مانند نبود بررسی nonce، نبود escape و نبود تست می‌تواند سایت را در معرض آسیب قرار دهد. در ادامه، ساختار داخلی، کاربردهای عملی و نکات امنیتی این تابع به‌تفصیل بررسی می‌شود.

چرا تشخیص وضعیت ورود کاربر حیاتی است؟

شاید در نگاه نخست، دانستن اینکه کاربر وارد شده است یا نه، موضوعی ساده به نظر برسد. اما همین تصمیم ساده، مرز میان یک تجربه کاربری روان و یک حفره امنیتی جدی را مشخص می‌کند. در پروژه‌های واقعی، پیاده‌سازی اشتباه این تشخیص باعث شده است که محتوای پرمیوم برای کاربران مهمان نمایش داده شود، سفارش‌های مشتریان خاص جابه‌جا شوند، یا فرم‌های حساس بدون بررسی هویت اجرا شوند. تابع is_user_logged_in() تنها یک بولین برنمی‌گرداند؛ این تابع پایه تصمیم‌های بزرگ‌تری است که با آن ساخته می‌شوند. اگر این پایه اشتباه گذاشته شود، لایه‌های بالاتر نیز بر همان خطا ساخته می‌شوند. به همین دلیل، بررسی این تابع نباید به یک خط شرط ساده محدود شود و نیازمند شناخت دقیق کوکی‌های احراز هویت، nonce‌ها و قواعد امنیتی وردپرس است.

تابع is_user_logged_in چیست؟

تابع is_user_logged_in() یک تابع هسته وردپرس است که در فایل wp-includes/pluggable.php تعریف شده است. این تابع بررسی می‌کند که آیا کاربر جاری در وردپرس شناسایی شده و کوکی احراز هویت معتبر دارد یا نه. خروجی این تابع دو حالت دارد: مقدار true اگر کاربر لاگین کرده و کوکی احراز هویت معتبر باشد، و مقدار false اگر کاربر مهمان باشد یا کوکی منقضی شده باشد. نکته مهم این است که این تابع برخلاف current_user_can() که بررسی می‌کند آیا کاربر اجازه انجام یک کار مشخص را دارد، تنها به وضعیت ورود کاربر توجه دارد. ترکیب این دو تابع است که امنیت منطقی سایت را می‌سازد و در ادامه به تفصیل به آن پرداخته می‌شود.

امضای تابع و پارامترها

امضای دقیق این تابع بدون هیچ پارامتر ورودی است و خروجی بولی می‌دهد. این سادگی ظاهری، گاهی باعث فراموشی نکات مهم‌تری می‌شود؛ به‌خصوص در پروژه‌هایی که با کش (Cache) و REST API سروکار دارند. برای بررسی وضعیت ورود یک کاربر خاص (نه کاربر جاری)، باید از توابع دیگر مانند get_user_by() و بررسی شیء کاربر استفاده کرد. خود is_user_logged_in() همیشه کاربر جاری را بررسی می‌کند.

سازوکار داخلی تابع

تابع is_user_logged_in() از دو تابع دیگر استفاده می‌کند: wp_get_current_user() که کاربر جاری را از WP_User برمی‌گرداند و WP_User::exists() که بررسی می‌کند آیا این شیء کاربر واقعی است یا نه. خود wp_get_current_user() نیز به نوبه خود از wp_set_current_user() که ممکن است قبلاً فراخوانی شده باشد، استفاده می‌کند. اگر هیچ کاربری تنظیم نشده باشد، این تابع تلاش می‌کند کاربر را از روی کوکی‌های احراز هویت (Authentication Cookies) بازیابی کند. کوکی احراز هویت وردپرس در واقع دو کوکی است: کوکی wordpress_logged_in_* که نامش با hash سایت ترکیب می‌شود و کوکی wordpress_sec_* برای مسیرهای امن. تابع is_user_logged_in() با رمزگشایی و بررسی امضای این کوکی‌ها تشخیص می‌دهد که آیا کاربر معتبر است یا نه. اگر امضا معتبر نباشد یا کوکی منقضی شده باشد، مقدار false بازمی‌گردد.

کاربردهای عملی در قالب

یکی از رایج‌ترین کاربردهای این تابع، نمایش شرطی محتوا در قالب است. به‌عنوان مثال، می‌توان پیام خوش‌آمد برای کاربران وارد شده نمایش داد و برای مهمان‌ها دکمه ورود آورد. نکات کلیدی در پیاده‌سازی صحیح شامل استفاده از esc_html() برای پاک‌سازی نام نمایشی کاربر، استفاده از esc_url() برای پاک‌سازی URL ورود و استفاده از wp_get_current_user() به‌جای دسترسی مستقیم به متغیرهای جهانی است. برای اطلاعات بیشتر درباره نحوه استفاده از توابع پاک‌سازی، می‌توانید به راهنمای تابع esc_html در وردپرس مراجعه کنید. کاربرد رایج دیگر، مخفی‌کردن بخش‌هایی از منو است؛ به‌طوری‌که لینک حساب کاربری و خروج تنها برای اعضا نمایش داده شود و برای مهمان‌ها لینک ورود و ثبت‌نام ظاهر شود.

استفاده در AJAX و REST API

در فرایندهای AJAX، وردپرس دو اکشن جداگانه دارد: wp_ajax_my_action که تنها برای کاربران وارد شده اجرا می‌شود و wp_ajax_nopriv_my_action که برای مهمان‌ها اجرا می‌شود. این ساختار در راهنمای هوک wp_ajax در وردپرس به تفصیل بررسی شده است. نکته بسیار مهم این است که در AJAX همیشه باید nonce بررسی شود. متأسفانه برخی توسعه‌دهندگان تنها به بررسی وضعیت ورود اکتفا می‌کنند و همین امر یک حفره CSRF (Cross-Site Request Forgery) ایجاد می‌کند. برای مطالعه بیشتر درباره این توابع به راهنمای wp_verify_nonce مراجعه کنید. پاسخی که در انتهای پردازش بازگردانده می‌شود، معمولاً با توابع wp_send_json_success و wp_send_json_error تولید می‌شود که توضیحات آن در راهنمای wp_send_json آمده است. در REST API نیز، مسیرهای ثبت‌شده با register_rest_route و پارامتر permission_callback می‌توانند از is_user_logged_in() یا ترکیب آن با current_user_can() استفاده کنند. مطالب تکمیلی در راهنمای register_rest_route آمده است.

نکات امنیتی و اشتباهات رایج

اشتباه اول، نبود بررسی nonce در فرم‌ها است. اگر فرمی تنها با is_user_logged_in() محافظت شود، هر کاربر وارد‌شده دیگری می‌تواند با یک درخواست ساخته‌شده، عملیات را اجرا کند. همیشه در کنار بررسی وضعیت ورود، از wp_nonce_field() و wp_verify_nonce() استفاده کنید. اشتباه دوم، نبود escape در خروجی است. نام کاربر، شناسه، آدرس و هر داده کاربری باید با توابع پاک‌سازی مناسب عبور داده شود. اشتباه سوم، نبود تست است. همیشه دو سناریو را آزمایش کنید: کاربر وارد شده و کاربر مهمان. در محیط Staging و با ابزارهایی مانند Playwright می‌توان این تست‌ها را خودکار کرد. اشتباه چهارم، استفاده در کش است. اگر صفحه‌ای که از is_user_logged_in() استفاده می‌کند کش شود، نتیجه ممکن است برای همه کاربران یکسان نمایش داده شود. این مشکل به‌خصوص در افزونه‌های Cache و CDN رخ می‌دهد. راه‌حل، استفاده از Fragment Cache یا تنظیم Vary: Cookie در پاسخ HTTP است. اشتباه پنجم، فرض بر پایدار بودن وضعیت در هر لحظه است. اگر کاربر جاری به‌صورت برنامه‌نویسی با wp_set_current_user() تغییر داده شود، is_user_logged_in() نیز تحت تأثیر قرار می‌گیرد. در کارهای پس‌زمینه این نکته اهمیت دارد. تابع current_user_can() برای بررسی سطح دسترسی پس از تأیید ورود کاربرد دارد. راهنمای جامع این تابع در صفحه current_user_can موجود است. توابع شرطی مانند is_single() و is_page() در کنار is_user_logged_in() ترکیب‌های قدرتمندی می‌سازند؛ نمونه‌ها در راهنمای is_single و راهنمای is_page آمده است. برای ساخت شورت‌کدهای شرطی بر اساس وضعیت ورود می‌توان از add_shortcode() استفاده کرد؛ مثال‌ها در راهنمای add_shortcode. همچنین برای ساخت ویجت‌های آگاه به وضعیت ورود، register_widget() کاربرد دارد که توضیحات آن در راهنمای register_widget ارائه شده است. بارگذاری بخش‌های شرطی قالب نیز با توابعی مانند get_header() و get_footer() انجام می‌شود که در راهنمای get_header به آن پرداخته شده است. در Authentication در ویکی‌پدیا می‌توانید مفهوم پایه احراز هویت را در سطح بین‌المللی دنبال کنید.

تحلیل فنی پیشرفته

در نگاه مهندسی، is_user_logged_in() تنها یک شرط نیست؛ این تابع یک نقطه تصمیم (Decision Point) است که در چند لایه معنایی متفاوت ظاهر می‌شود. لایه اول لایه HTTP است که کوکی‌های احراز هویت در هر درخواست بررسی می‌شوند و این بررسی در wp_validate_auth_cookie() انجام می‌شود و شامل رمزگشایی و بررسی امضای hash است. لایه دوم لایه کشینگ است. در سایت‌های پربازدید، اجرای این تابع روی هر درخواست می‌تواند هزینه محسوسی داشته باشد. راه‌حل‌های حرفه‌ای شامل استفاده از Edge Cache با Vary بر اساس کوکی یا Page Cache تفکیک‌شده برای مهمان و عضو است. لایه سوم لایه API است. در REST API و GraphQL، این تابع اغلب در permission_callback ظاهر می‌شود. اما تأکید بر این نکته حیاتی است که تنها بررسی وضعیت ورود کافی نیست و باید با current_user_can() و مدیریت nonce ترکیب شود. لایه چهارم لایه تست است. واحدهای تست باید هم حالت مهمان و هم حالت عضو را پوشش دهند. ابزارهایی مانند Brain Monkey و WP_Mock برای تست رفتار این تابع در واحدهای مستقل کاربرد دارند. لایه پنجم لایه Observability است. در پروژه‌های بزرگ، ثبت رخدادهای ورود و خروج و بررسی الگوهای غیرعادی می‌تواند به کشف حملات کمک کند. در پروژه‌هایی که با Headless WordPress سروکار دارند، این تابع در سمت بک‌اند اجرا می‌شود و فرانت‌اند تنها وضعیت را از طریق API دریافت می‌کند. بنابراین طراحی درست پاسخ‌های API در این معماری اهمیت دوچندانی دارد. در Multisite نیز، رفتار این تابع ممکن است بسته به شبکه و تنظیمات متفاوت باشد. کوکی‌های احراز هویت در Multisite با پارامترهای مخصوص تنظیم می‌شوند و ممکن است دامنه‌شان روی زیرشبکه‌ها متفاوت باشد.

پرسش‌های پرتکرار

آیا is_user_logged_in در زمان کش شدن صفحه درست کار می‌کند؟ به‌صورت پیش‌فرض ممکن است پاسخ کش‌شده برای همه کاربران یکسان باشد. باید از Cache Segmentation یا Fragment Cache استفاده کرد. آیا این تابع برای بررسی کاربر خاص مناسب است؟ خیر. این تابع تنها کاربر جاری را بررسی می‌کند. برای کاربر خاص از get_user_by() یا get_userdata() استفاده کنید. آیا در REST API استفاده از این تابع امن است؟ به‌تنهایی نه. باید در ترکیب با current_user_can() و مدیریت nonce استفاده شود. آیا در پوسته پلاگین‌های پرمیوم می‌توان به این تابع اتکا کرد؟ این تابع قابل بازنویسی (Pluggable) است، بنابراین ممکن است افزونه‌ای آن را تغییر دهد. در پروژه‌های حساس، در نظر گرفتن این امکان منطقی است. چگونه این تابع را تست کنیم؟ با ابزارهایی مانند PHPUnit و WP_Mock یا با تست‌های End-to-End مانند Playwright. همچنین بررسی در محیط Staging پیشنهاد می‌شود.

نتیجه و مسیر ادامه

تابع is_user_logged_in() یک تابع ساده با پیامدهای عمیق است. درست استفاده‌کردن از آن یعنی درک درست از کوکی‌های احراز هویت، کش، امنیت nonce و ترکیب با توابع دسترسی‌محور. اشتباه‌های این تابع اغلب تنها در ظاهر ساده‌اند اما در سطح امنیتی پیامدهای جدی دارند. اگر این تابع را در پروژه‌ای واقعی استفاده کرده‌اید و رفتار عجیبی از آن دیده‌اید — به‌خصوص در ترکیب با کش یا Multisite — تجربه‌تان می‌تواند برای خواننده بعدی بسیار مفید باشد. کدام سناریو بیشترین زمان را از شما گرفت؟ و اگر راه‌حل متفاوتی پیدا کردید، آن را در دیدگاه‌ها به اشتراک بگذارید.