मैं इसी तरह के एक मुद्दे को संबोधित करने की कोशिश कर रहा हूं। मेरे उपयोगकर्ताओं को उनके द्वारा किए जाने वाले प्रत्येक अनुरोध के लिए प्रमाणित करने की आवश्यकता है। मैं बैकएंड ऐप (जेडब्ल्यूटी टोकन की मान्यता) द्वारा उपयोगकर्ताओं को कम से कम एक बार प्रमाणित करने पर ध्यान केंद्रित कर रहा हूं, लेकिन उसके बाद, मैंने फैसला किया कि मुझे अब बैकएंड की आवश्यकता नहीं होनी चाहिए।
मैंने किसी भी Nginx प्लगइन की आवश्यकता से बचने के लिए चुना जो डिफ़ॉल्ट रूप से शामिल नहीं है। अन्यथा आप nginx-jwt या Lua स्क्रिप्टिंग की जांच कर सकते हैं और ये संभवत: महान समाधान होंगे।
प्रमाणीकरण को संबोधित करना
अब तक मैंने निम्नलिखित कार्य किए हैं:
प्रमाणीकरण का उपयोग करके Nginx को सौंप दिया auth_request
। यह एक internal
स्थान कहता है जो मेरे बैकएंड टोकन सत्यापन समापन बिंदु के अनुरोध को पारित करता है। यह अकेले अधिक संख्या में मान्यताओं को संभालने के मुद्दे को संबोधित नहीं करता है।
टोकन सत्यापन का परिणाम एक proxy_cache_key "$cookie_token";
निर्देश का उपयोग करके कैश किया जाता है । सफल टोकन सत्यापन के बाद, बैकएंड एक Cache-Control
निर्देश जोड़ता है जो कि नगनेक्स को केवल टोकन को 5 मिनट तक कैश करने के लिए कहता है। इस बिंदु पर, किसी भी टोकन का सत्यापन एक बार कैश में हो जाने के बाद, उसी उपयोगकर्ता / टोकन से बाद के अनुरोधों ने एंडरॉयड बैकएंड को स्पर्श नहीं किया है!
अवैध टोकन द्वारा संभावित बाढ़ के खिलाफ अपने बैकएंड ऐप की रक्षा करने के लिए, मैंने कैश को मान्यताओं से भी इनकार कर दिया, जब मेरा बैकएंड समापन बिंदु 401 लौटता है। ये ऐसे अनुरोधों के साथ संभावित रूप से नगनेक्स कैश भरने से बचने के लिए थोड़े समय के लिए कैश होते हैं।
मैंने कुछ अतिरिक्त सुधार जोड़े हैं जैसे कि एक लॉगआउट समापन बिंदु जो 401 को वापस करके एक टोकन को अमान्य करता है (जो कि नगनेक्स द्वारा कैश भी किया गया है) ताकि यदि उपयोगकर्ता लॉगआउट पर क्लिक करता है, तो टोकन अब भी समाप्त नहीं होने पर भी उपयोग नहीं किया जा सकता है।
इसके अलावा, मेरे Nginx कैश में प्रत्येक टोकन के लिए, JSON ऑब्जेक्ट के रूप में संबद्ध उपयोगकर्ता शामिल है, जो मुझे इस जानकारी की आवश्यकता होने पर DB से इसे प्राप्त करने से बचाता है; और मुझे टोकन डिक्रिप्ट करने से भी बचाता है।
टोकन आजीवन और ताज़ा टोकन के बारे में
5 मिनट के बाद, टोकन कैश में समाप्त हो जाएगा, इसलिए बैकएंड को फिर से क्वियर किया जाएगा। यह सुनिश्चित करने के लिए है कि आप एक टोकन को अमान्य कर सकते हैं, क्योंकि उपयोगकर्ता लॉग आउट करता है, क्योंकि यह समझौता किया गया है, और इसी तरह। बैकएंड में उचित कार्यान्वयन के साथ इस तरह की आवधिक पुनरावृत्ति, मुझे ताज़ा टोकन का उपयोग करने से बचाती है।
परंपरागत रूप से ताज़ा टोकन का उपयोग एक नए पहुंच टोकन का अनुरोध करने के लिए किया जाएगा; वे आपके बैकएंड में संग्रहीत किए जाएंगे और आप सत्यापित करेंगे कि एक्सेस टोकन के लिए एक अनुरोध एक ताज़ा टोकन के साथ किया गया है जो इस विशिष्ट उपयोगकर्ता के लिए डेटाबेस में आपके साथ मेल खाता है। यदि उपयोगकर्ता लॉग आउट करता है, या टोकन से समझौता किया जाता है, तो आप अपने DB में ताज़ा टोकन को हटा / अमान्य कर देंगे, ताकि अमान्य ताज़ा टोकन का उपयोग करके नए टोकन के लिए अगला अनुरोध विफल हो जाए।
संक्षेप में, ताज़ा टोकन में आमतौर पर एक लंबी वैधता होती है और हमेशा बैकएंड के खिलाफ जांच की जाती है। वे एक्सेस टोकन उत्पन्न करने के लिए उपयोग किए जाते हैं जिनकी बहुत कम वैधता (कुछ मिनट) है। ये एक्सेस टोकन सामान्य रूप से आपके बैकेंड तक पहुंचते हैं लेकिन आप केवल उनके हस्ताक्षर और समाप्ति तिथि की जांच करते हैं।
यहाँ मेरे सेटअप में, हम एक लंबी वैधता के साथ टोकन का उपयोग कर रहे हैं (घंटे या दिन हो सकते हैं), जिसमें एक एक्सेस टोकन और एक ताज़ा टोकन दोनों की समान भूमिका और विशेषताएं हैं। क्योंकि हमारे पास उनका सत्यापन और अमान्यकरण Nginx द्वारा कैश किया गया है, वे केवल 5 मिनट में एक बार बैकएंड द्वारा पूरी तरह से सत्यापित होते हैं। तो हम जोड़े हुए जटिलता के बिना ताज़ा टोकन (जल्दी से एक टोकन को अमान्य करने में सक्षम) का उपयोग करने का लाभ रखते हैं। और सरल मान्यता कभी भी आपके बैकएंड तक नहीं पहुंचती है जो कि Nginx कैश की तुलना में कम से कम 1 ऑर्डर है, भले ही वह केवल हस्ताक्षर और समाप्ति तिथि की जाँच के लिए उपयोग किया गया हो।
इस सेटअप के साथ, मैं अपने बैकएंड में प्रमाणीकरण को अक्षम कर सकता हूं, क्योंकि आने वाले सभी अनुरोध auth_request
इसे छूने से पहले नग्नेक्स निर्देश पर पहुंचते हैं ।
यदि आप किसी भी प्रकार के प्रति संसाधन प्राधिकरण को निष्पादित करने की आवश्यकता को पूरी तरह से हल नहीं करते हैं, लेकिन कम से कम आपने मूल प्राधिकरण भाग को सहेज लिया है। और आप टोकन को डिक्रिप्ट करने से भी बच सकते हैं या टोकन डेटा तक पहुंचने के लिए एक डीबी लुकअप कर सकते हैं क्योंकि नग्नेक्स कैश की गई प्रतिक्रिया का डेटा हो सकता है और इसे बैकएंड पर वापस भेज सकते हैं।
अब, मेरी सबसे बड़ी चिंता यह है कि मैं इसे साकार किए बिना सुरक्षा से संबंधित कुछ स्पष्ट तोड़ सकता हूं। यह कहा जा रहा है, किसी भी प्राप्त टोकन को अभी भी कम से कम एक बार Nginx द्वारा कैश किए जाने से पहले मान्य किया गया है। कोई भी टेम्पर्ड टोकन अलग होगा इसलिए कैश को हिट नहीं करेगा क्योंकि कैश की भी अलग होगी।
इसके अलावा, शायद यह ध्यान देने योग्य है कि एक वास्तविक विश्व प्रमाणीकरण एक अतिरिक्त नॉनस या कुछ और उत्पन्न करने (और सत्यापन) द्वारा टोकन चोरी के खिलाफ लड़ाई लड़ेगा।
यहाँ मेरे ऐप के लिए मेरे Nginx कॉन्फिग का सरलीकृत अर्क है:
# Cache for internal auth checks
proxy_cache_path /usr/local/var/nginx/cache/auth levels=1:2 keys_zone=auth_cache:10m max_size=128m inactive=10m use_temp_path=off;
# Cache for content
proxy_cache_path /usr/local/var/nginx/cache/resx levels=1:2 keys_zone=content_cache:16m max_size=128m inactive=5m use_temp_path=off;
server {
listen 443 ssl http2;
server_name ........;
include /usr/local/etc/nginx/include-auth-internal.conf;
location /api/v1 {
# Auth magic happens here
auth_request /auth;
auth_request_set $user $upstream_http_X_User_Id;
auth_request_set $customer $upstream_http_X_Customer_Id;
auth_request_set $permissions $upstream_http_X_Permissions;
# The backend app, once Nginx has performed internal auth.
proxy_pass http://127.0.0.1:5000;
proxy_set_header X-User-Id $user;
proxy_set_header X-Customer-Id $customer;
proxy_set_header X-Permissions $permissions;
# Cache content
proxy_cache content_cache;
proxy_cache_key "$request_method-$request_uri";
}
location /api/v1/Logout {
auth_request /auth/logout;
}
}
अब, आंतरिक /auth
समापन बिंदु के लिए कॉन्फ़िगरेशन एक्सट्रैक्शन इस प्रकार है /usr/local/etc/nginx/include-auth-internal.conf
:
# Called before every request to backend
location = /auth {
internal;
proxy_cache auth_cache;
proxy_cache_methods GET HEAD POST;
proxy_cache_key "$cookie_token";
# Valid tokens cache duration is set by backend returning a properly set Cache-Control header
# Invalid tokens are shortly cached to protect backend but not flood Nginx cache
proxy_cache_valid 401 30s;
# Valid tokens are cached for 5 minutes so we can get the backend to re-validate them from time to time
proxy_cache_valid 200 5m;
proxy_pass http://127.0.0.1:1234/auth/_Internal;
proxy_set_header Host ........;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Accept application/json;
}
# To invalidate a not expired token, use a specific backend endpoint.
# Then we cache the token invalid/401 response itself.
location = /auth/logout {
internal;
proxy_cache auth_cache;
proxy_cache_key "$cookie_token";
# Proper caching duration (> token expire date) set by backend, which will override below default duration
proxy_cache_valid 401 30m;
# A Logout requests forces a cache refresh in order to store a 401 where there was previously a valid authorization
proxy_cache_bypass 1;
# This backend endpoint always returns 401, with a cache header set to the expire date of the token
proxy_pass http://127.0.0.1:1234/auth/_Internal/Logout;
proxy_set_header Host ........;
proxy_pass_request_body off;
}
।
सेवारत सामग्री को संबोधित करना
अब प्रमाणीकरण डेटा से अलग हो गया है। चूंकि आपने बताया था कि यह प्रत्येक उपयोगकर्ता के लिए समान था, इसलिए सामग्री को नगनेक्स (मेरे उदाहरण में, content_cache
ज़ोन में) भी कैश किया जा सकता है ।
अनुमापकता
यह परिदृश्य बॉक्स से बाहर काम करता है यह मानते हुए कि आपके पास एक Nginx सर्वर है। एक वास्तविक दुनिया के परिदृश्य में आपके पास संभवतः उच्च उपलब्धता है, जिसका अर्थ है कई नगनेक्स उदाहरण, संभवतः आपके (लारवेल) बैकएंड एप्लिकेशन की मेजबानी भी करते हैं। उस स्थिति में, आपके उपयोगकर्ता जो भी अनुरोध करते हैं, वह आपके किसी भी नगनेक्स सर्वर को भेजा जा सकता है, और जब तक वे सभी स्थानीय रूप से टोकन को कैश नहीं कर लेते, वे इसे सत्यापित करने के लिए आपके बैकेंड तक पहुंचते रहेंगे। सर्वर की एक छोटी संख्या के लिए, इस समाधान का उपयोग करना अभी भी बड़े लाभ लाएगा।
हालांकि, यह ध्यान रखना महत्वपूर्ण है कि एकाधिक नगनेक्स सर्वर (और इस प्रकार कैश) के साथ आप सर्वर साइड पर लॉग आउट करने की क्षमता खो देते हैं क्योंकि आप इन सभी पर टोकन कैश को शुद्ध करने के लिए (ताज़ा करने के लिए) असमर्थ हैं, जैसे /auth/logout
मेरे उदाहरण में है। आप केवल 5mn टोकन कैश अवधि के साथ बचे हैं, जो आपके बैकएंड को जल्द ही बंद करने के लिए मजबूर करेगा, और Nginx को बताएगा कि अनुरोध अस्वीकार कर दिया गया है। लॉग आउट करते समय क्लाइंट पर टोकन हेडर या कुकी को हटाने के लिए एक आंशिक समाधान है।
किसी भी टिप्पणी का बहुत स्वागत और सराहना की जाएगी!