সমস্ত ব্যবহারকারীর জন্য অনুমোদিত অনুরোধগুলি ক্যাশে করা হচ্ছে


9

আমি এমন একটি ওয়েব অ্যাপে কাজ করছি যা একইসাথে সামগ্রীর অনুরোধের জন্য একযোগে ব্যবহারকারীদের, যাদের অনুমোদিত হতে হবে তাদের খুব বড় প্রবণতাগুলির সাথে ডিল করতে হবে। এর বর্তমান অবস্থায় এটি একটি 32-কোর এডাব্লুএস উদাহরণে সম্পূর্ণ পঙ্গু।

(নোট করুন যে আমরা বিপরীত প্রক্সি হিসাবে Nginx ব্যবহার করছি)

প্রতিক্রিয়াটি কেবল ক্যাশে করা যায় না, যেহেতু সবচেয়ে খারাপ ক্ষেত্রে, তাদের জেডব্লিউটি ডিকোডিং করে ব্যবহারকারীর অনুমোদন দেওয়া হয়েছে কিনা তা আমাদের অবশ্যই পরীক্ষা করা উচিত। এই পর্যন্ত Laravel 4, যা সর্বাধিক সম্মত হবে অগ্নিসংযোগ আমাদের প্রয়োজন, হয় ধীর , পিএইচপি-FPM এবং OpCache সক্রিয় এমনকি। এটি বেশীরভাগ বুটস্ট্র্যাপিং পর্বের কারণে।

কেউ এই প্রশ্ন জিজ্ঞাসা করতে পারে "আপনি যদি জানতেন যে এই সমস্যা হতে চলেছে তবে আপনি কেন প্রথম স্থানে পিএইচপি এবং লারাভেল ব্যবহার করলেন?" - তবে সেই সিদ্ধান্তটি ফিরে পেতে এখন অনেক দেরি!

সম্ভাব্য সমাধান

একটি সমাধান যা এগিয়ে দেওয়া হয়েছে তা হ'ল লারাভেল থেকে আউথ মডিউলটি একটি লাইটওয়েট বাহ্যিক মডিউল (সি এর মতো দ্রুত কিছুতে লিখিত) এর সন্ধান করা যার দায়বদ্ধতা ডাব্লুডাব্লুটিটি ডিকোড করা এবং সিদ্ধান্ত নিতে হবে যে ব্যবহারকারী সত্যায়িত কিনা।

একটি অনুরোধ প্রবাহ হবে:

  1. ক্যাশে হিট হয়েছে কিনা তা পরীক্ষা করুন (পিএইচপি-তে স্বাভাবিক হিসাবে পাস না হলে)
  2. টোকেনটি ডিকোড করুন
  3. এটি বৈধ কিনা তা পরীক্ষা করে দেখুন
  4. যদি বৈধ ক্যাশে থেকে পরিবেশন করা
  5. যদি অবৈধ হয় , এনগিনেক্সকে বলুন এবং তারপরে Nginx তারপরে পিএইচপিকে অনুরোধটি স্বাভাবিক হিসাবে মোকাবেলা করবে।

এটি একবারে আমরা কোনও একক ব্যবহারকারীর কাছে এই অনুরোধটি পরিবেশন করে এবং পরিবর্তে JWTs এবং এই ধরণের লেখার সাথে আসা অন্য কোনও ক্যাভেটের সাথে ডকোডিংয়ের সাথে হালকা হালকা মডিউলে পৌঁছানোর জন্য আমাদের পিএইচপি হিট করতে দেবে না।

এমনকি আমি এই কোডটি সরাসরি এনগিনেক্স এইচটিটিপি এক্সটেনশন মডিউল হিসাবে লিখতে ভাবছিলাম।

উদ্বেগ

আমার উদ্বেগ হ'ল আমি এর আগে কখনও এটি করে দেখিনি এবং আরও ভাল উপায় আছে কিনা তা নিয়ে ভাবছি।

এছাড়াও, দ্বিতীয়টি আপনি পৃষ্ঠায় যে কোনও ব্যবহারকারীর নির্দিষ্ট বিষয়বস্তু যুক্ত করবেন, এটি সম্পূর্ণ এই পদ্ধতিটিকে হত্যা করে।

এনগিনেক্সে সরাসরি আরও কী সহজ সমাধান পাওয়া যায়? বা আমাদের কি বার্নিশের মতো আরও বিশেষ কিছু ব্যবহার করতে হবে?

আমার প্রশ্নগুলো:

উপরের সমাধানটি কি বোধগম্য?

এটি সাধারণত কীভাবে যোগাযোগ করা হয়?

অনুরূপ বা আরও ভাল পারফরম্যান্স লাভের জন্য আরও ভাল উপায় কি?


আমি একই ধরণের সমস্যা নিয়ে ঝাঁপিয়ে পড়ছি। একটি ধারণা কয়েক) ক Nginx auth_request আপনার প্রমাণীকরণের মাইক্রোসার্চিসকে হস্তান্তর করতে সক্ষম হতে পারে, একটি Nginx মডিউল বিকাশের প্রয়োজনীয়তা হ্রাস করতে পারে। খ) বিকল্পভাবে, আপনার মাইক্রোসার্ভিস প্রমাণীকৃত ব্যবহারকারীদের একটি অস্থায়ী URL- এ পুনর্নির্দেশ করতে পারে যা জনসাধারণ, ক্যাশেযোগ্য এবং অনর্থ্য। এটি কিছু সুরক্ষা উত্সর্গ করেছে, যদি অস্থায়ী URL টি কোনও অবিশ্বস্ত ব্যবহারকারীর কাছে ফাঁস হয় তবে তারা এই সীমিত সময়ের জন্য সামগ্রীটি অ্যাক্সেস করতে পারে, অনেকটা OAuth বহনকারী টোকেনের মতো।
জেমস

আপনি কি এর সমাধান নিয়ে এসেছেন? আমি একই জিনিসটির মুখোমুখি হচ্ছি
টিম্বব্রোডার

দেখা যাচ্ছে যে অনুকূলিত ব্যাকএন্ড নোডগুলির একটি বৃহত্তর ক্লাস্টার থাকা সত্ত্বেও আমরা বোঝাটি মোকাবেলা করতে সক্ষম হয়েছি - তবে এই পদ্ধতির প্রতি আমার বড় আস্থা রয়েছে একটি দীর্ঘ ব্যয় সাশ্রয় সমাধান দীর্ঘমেয়াদী। আপনি যদি কিছু প্রতিক্রিয়া আগে থেকেই পরিবেশন করতে পারেন তবে আপনি যদি অনুরোধের আগমনের আগে ক্যাশে গরম করেন তবে ব্যাকএন্ড রিসোর্স সাশ্রয় এবং নির্ভরযোগ্যতা লাভ খুব বেশি হবে be
iamyojimbo

উত্তর:


9

আমি একটি অনুরূপ সমস্যা সম্বোধন করার চেষ্টা করা হয়েছে। আমার ব্যবহারকারীদের প্রতিটি অনুরোধের জন্য প্রমাণীকরণ করা দরকার। আমি ব্যাক-এন্ড অ্যাপ্লিকেশন (জেডাব্লুটি টোকেনের বৈধতা) দ্বারা কমপক্ষে একবার ব্যবহারকারীদের অনুমোদনে ফোকাস করছি, তবে এর পরে, আমি সিদ্ধান্ত নিয়েছি যে আমার আর ব্যাকএন্ডের দরকার নেই।

আমি ডিফল্টরূপে অন্তর্ভুক্ত না এমন কোনও এনগিনেক্স প্লাগইন প্রয়োজনীয়তা এড়াতে পছন্দ করেছি। অন্যথায় আপনি nginx-jwt বা লুয়া স্ক্রিপ্টিং পরীক্ষা করতে পারেন এবং এগুলি সম্ভবত দুর্দান্ত সমাধান হতে পারে।

প্রমাণীকরণের ঠিকানা

এখনও অবধি আমি নিম্নলিখিতটি করেছি:

  • Nginx ব্যবহার করে প্রমাণীকরণ প্রেরণ auth_request। এটি এমন একটি internalঅবস্থানকে কল করে যা আমার ব্যাকএন্ড টোকেন বৈধতা শেষ পয়েন্টে অনুরোধটি পাস করে passes এটি কেবলমাত্র উচ্চ সংখ্যক বৈধতা হ্যান্ডেল করার বিষয়টি বিবেচনা করে না।

  • টোকেন বৈধতার ফলাফলটি একটি proxy_cache_key "$cookie_token";নির্দেশিকা ব্যবহার করে ক্যাশে করা হয় । সফল টোকেন যাচাইকরণের পরে, ব্যাকএন্ড একটি Cache-Controlনির্দেশিকা যুক্ত করে যা Nginx কে কেবল 5 মিনিটের জন্য টোকেন ক্যাশে রাখতে বলে। এই মুহুর্তে, একবারে যাচাইযোগ্য যে কোনও লেখক টোকেন ক্যাশে রয়েছে, একই ব্যবহারকারী / টোকেনের পরবর্তী অনুরোধগুলি আর লেখকের ব্যাকএন্ডটি স্পর্শ করবে না!

  • অবৈধ টোকেন দ্বারা সম্ভাব্য বন্যার বিরুদ্ধে আমার ব্যাকএন্ড অ্যাপ্লিকেশনটিকে সুরক্ষিত করার জন্য, আমি যখন আমার ব্যাকেন্ডের শেষ পয়েন্টটি 401 ফিরে আসে তখন আমি বৈধতাও অস্বীকার করি। এই জাতীয় অনুরোধগুলি সহ সম্ভাব্যভাবে এনগিনেক্স ক্যাশে পূরণ করা এড়াতে এইগুলি কেবলমাত্র একটি স্বল্প সময়ের জন্য ক্যাশে রাখা হয়।

আমি বেশ কয়েকটি অতিরিক্ত উন্নতি যুক্ত করেছি যেমন একটি লগআউট শেষ পয়েন্ট যা 401 ফেরার মাধ্যমে একটি টোকেনকে অবৈধ করে তোলে (যা এনগিনেক্স দ্বারাও ক্যাশে করা হয়) যাতে ব্যবহারকারী লগআউট ক্লিক করেন, টোকেনটির মেয়াদ শেষ না হওয়া সত্ত্বেও আর ব্যবহার করা যাবে না।

এছাড়াও, আমার এনগিনেক্স ক্যাশে প্রতিটি টোকেনের জন্য রয়েছে, জেএসওএন অবজেক্ট হিসাবে সম্পর্কিত ব্যবহারকারী, যা আমাকে এই তথ্যের প্রয়োজন হলে এটি ডিবি থেকে আনতে বাঁচায়; এবং টোকেনটি ডিক্রিপ্ট করা থেকে আমাকে বাঁচায়।

টোকেন জীবনকাল এবং রিফ্রেশ টোকেন সম্পর্কে

5 মিনিটের পরে, টোকেনটি ক্যাশে শেষ হয়ে যাবে, তাই ব্যাকএন্ড আবার জিজ্ঞাসা করা হবে। এটি নিশ্চিত করার জন্য আপনি কোনও টোকেনকে অবৈধ করতে পেরেছেন, কারণ ব্যবহারকারী লগ আউট করেছেন, কারণ এটি আপস করা হয়েছে and ব্যাকএন্ডে যথাযথ প্রয়োগের সাথে এই জাতীয় পর্যায়ক্রমে পুনরায় বৈধকরণ আমাকে রিফ্রেশ টোকেন ব্যবহার করতে এড়িয়ে যায়।

Accessতিহ্যগতভাবে রিফ্রেশ টোকেনগুলি একটি নতুন অ্যাক্সেস টোকেনের অনুরোধ করতে ব্যবহৃত হবে; এগুলি আপনার ব্যাকএন্ডে সংরক্ষণ করা হবে এবং আপনি যাচাই করবেন যে অ্যাক্সেস টোকেনের জন্য একটি অনুরোধটি একটি নির্দিষ্ট রিফ্রেশ টোকেন দিয়ে তৈরি করা হয়েছে যা এই নির্দিষ্ট ব্যবহারকারীর জন্য আপনার ডেটাবেজে থাকা সাথে মেলে। যদি ব্যবহারকারী লগ আউট করে, বা টোকেনগুলি আপস করা হয় তবে আপনি আপনার ডিবিতে রিফ্রেশ টোকেনটি মুছে / বাতিল করবেন যাতে অবৈধভাবে রিফ্রেশ টোকেন ব্যবহার করে নতুন টোকেনের জন্য পরবর্তী অনুরোধটি ব্যর্থ হয়।

সংক্ষেপে, রিফ্রেশ টোকেনগুলির সাধারণত একটি দীর্ঘ মেয়াদ থাকে এবং সর্বদা ব্যাকএন্ডের বিপরীতে পরীক্ষা করা হয়। এগুলি অ্যাক্সেস টোকেনগুলি তৈরি করতে ব্যবহৃত হয় যা খুব স্বল্প বৈধতা (কয়েক মিনিট) রয়েছে। এই অ্যাক্সেস টোকেনগুলি সাধারণত আপনার ব্যাকএন্ডে পৌঁছায় তবে আপনি কেবল তাদের স্বাক্ষর এবং মেয়াদোত্তীকরণের তারিখটি পরীক্ষা করেন।

এখানে আমার সেটআপে, আমরা একটি দীর্ঘতর বৈধতার সাথে টোকেন ব্যবহার করছি (ঘন্টা বা একটি দিন হতে পারে), যার অ্যাক্সেস টোকেন এবং রিফ্রেশ টোকেন উভয়ের একই ভূমিকা এবং বৈশিষ্ট্য রয়েছে। যেহেতু Nginx দ্বারা আমাদের তাদের বৈধতা এবং অবৈধকরণ ক্যাশে করেছে, তারা প্রতি 5 মিনিটের মধ্যে কেবল ব্যাকএন্ড দ্বারা সম্পূর্ণরূপে যাচাই করা হয়। সুতরাং আমরা যুক্ত জটিলতা ছাড়াই রিফ্রেশ টোকেনগুলি (দ্রুত একটি টোকেনকে অকার্যকর করতে সক্ষম) ব্যবহারের সুবিধা রাখি। এবং সহজ বৈধতা কখনই আপনার ব্যাকেন্ডে পৌঁছায় না যা কেবলমাত্র স্বাক্ষর এবং মেয়াদোত্তীকরণের তারিখ পরীক্ষার জন্য ব্যবহৃত হলেও, এনগিনেক্স ক্যাশে থেকে কমপক্ষে 1 মাপের ধীরে ধীরে কম থাকে।

এই সেটআপের সাহায্যে আমি আমার ব্যাকএন্ডে প্রমাণীকরণ অক্ষম করতে পারি, যেহেতু সমস্ত আগত অনুরোধগুলি auth_requestস্পর্শ করার আগে এনগিনেক্সের নির্দেশিকায় পৌঁছে ।

যদি আপনাকে কোনও উত্স-প্রতি সংস্থান অনুমোদনের প্রয়োজন হয় তবে সমস্যাটি সম্পূর্ণরূপে সমাধান করে না তবে অন্তত আপনি মৌলিক অনুমোদনের অংশটি সংরক্ষণ করেছেন। এবং আপনি এমনকি টোকেনটি ডিক্রিপ্ট করা এড়াতে পারবেন বা টোকেন ডেটা অ্যাক্সেস করতে একটি ডিবি লুকআপ করতে পারবেন যেহেতু এনগিনেক্স ক্যাশেড লেখক প্রতিক্রিয়াতে ডেটা থাকতে পারে এবং এটি ব্যাকএন্ডে ফিরে যেতে পারে।

এখন, আমার সবচেয়ে বড় উদ্বেগ হ'ল আমি বুঝতে পারি না যে এটি সুরক্ষার সাথে সম্পর্কিত কিছু স্পষ্ট করে ফেলছি। বলা হচ্ছে, যে কোনও প্রাপ্ত টোকেন এখনও কমপক্ষে একবার 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জোনে)।

স্কেলেবিলিটি

আপনার কাছে একটি এনগিনেক্স সার্ভার রয়েছে তা ধরে নিয়ে এই দৃশ্যটি বক্সের বাইরে দুর্দান্ত কাজ করে। বাস্তব বিশ্বের দৃশ্যে আপনার সম্ভবত উচ্চ প্রাপ্যতা রয়েছে যার অর্থ একাধিক এনগিনেক্স উদাহরণ, সম্ভবত আপনার (লারাভেল) ব্যাকএন্ড অ্যাপ্লিকেশনটি হোস্ট করে। সেক্ষেত্রে আপনার ব্যবহারকারীরা যে কোনও অনুরোধ করবেন তা আপনার এনগিনেক্স সার্ভারগুলির যে কোনওটিতে প্রেরণ করা যেতে পারে এবং যতক্ষণ না তারা সকলে স্থানীয়ভাবে টোকেনকে ক্যাশ না করে, তারা এটি যাচাই করার জন্য আপনার ব্যাকএন্ডে পৌঁছে যাবে। অল্প সংখ্যক সার্ভারের জন্য, এই সমাধানটি ব্যবহার করা এখনও বড় সুবিধা বয়ে আনবে।

তবে এটি লক্ষণীয় গুরুত্বপূর্ণ যে একাধিক এনজিন্স সার্ভারের সাথে (এবং এইভাবে ক্যাশে) আপনি সার্ভার সাইডে লগ আউট করার ক্ষমতা হারাবেন কারণ আপনি তাদের সকলের টোকেন ক্যাশে মুছে ফেলতে (পুনরায় একটি রিফ্রেশ জোর করে) অক্ষম করেছেন like /auth/logoutআমার উদাহরণে না। আপনি কেবলমাত্র 5 মিলিয়ন টোকেন ক্যাশে সময়কাল রেখে গেছেন যা আপনার ব্যাকএন্ড শিগগিরই জিজ্ঞাসা করতে বাধ্য করবে, এবং এনগিনেক্সকে জানিয়ে দেবে যে অনুরোধ প্রত্যাখ্যান করা হয়েছে। একটি আংশিক workaround হ'ল লগ আউট করার সময় ক্লায়েন্টের টোকেন শিরোনাম বা কুকি মুছে ফেলা।

কোন মন্তব্য খুব স্বাগত জানানো হবে এবং প্রশংসা করা হবে!


আপনার আরও অনেকগুলি উপার্জন করা উচিত! খুব সহায়ক, ধন্যবাদ!
গের্শন পাপি

"আমি কয়েকটি অতিরিক্ত উন্নতি যুক্ত করেছি যেমন লগআউট শেষ পয়েন্ট যা 401 (যা এনগিনেক্স দ্বারা ক্যাশে করা হয়) ফিরিয়ে দিয়ে টোকেনকে অবৈধ করে তোলে যাতে ব্যবহারকারী লগআউট ক্লিক করেন, টোকেনটির মেয়াদ শেষ না হওয়া সত্ত্বেও আর ব্যবহার করা যাবে না। " - এই চালাক! , তবে আপনি কি আসলে আপনার ব্যাকএন্ডে টোকেনকেও কালো তালিকাভুক্ত করছেন, যাতে ক্যাশে নেমে আসে বা কোনও কিছু হয়, ব্যবহারকারী এখনও সেই নির্দিষ্ট টোকেনটি দিয়ে লগইন করতে সক্ষম হয় না?
gaurav5430

"তবে এটি লক্ষণীয় গুরুত্বপূর্ণ যে একাধিক এনগিনেক্স সার্ভারের সাথে (এবং এইভাবে ক্যাশে) আপনি সার্ভার সাইডে লগ আউট করার ক্ষমতা হারাবেন কারণ আপনি সেগুলির সমস্ত টোকেন ক্যাশে মুছে ফেলতে (পুনরায় রিফ্রেশ জোর করে) অক্ষম করেছেন, লাইক / প্রমান / লগআউট আমার উদাহরণে করে does " তুমি কি বিস্তারিত বলতে পারো?
gaurav5430
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.