लेख के लेखक, जिसका अनुवाद हम आज प्रकाशित कर रहे हैं, का कहना है कि अब आप प्रमाणीकरण सेवाओं की बढ़ती लोकप्रियता जैसे कि Google Firebase प्रमाणीकरण, AWS Cognito और Auth0 का अवलोकन कर सकते हैं। पासपोर्ट.जेएस जैसे सामान्य समाधान उद्योग मानक बन गए हैं। लेकिन, मौजूदा स्थिति को देखते हुए, यह आम बात हो गई है कि डेवलपर्स कभी भी पूरी तरह से समझ नहीं पाते हैं कि प्रमाणीकरण प्रणाली के संचालन में कौन से तंत्र शामिल हैं।
यह सामग्री Node.js. में उपयोगकर्ता प्रमाणीकरण के आयोजन की समस्या के लिए समर्पित है इसमें, एक व्यावहारिक उदाहरण पर, सिस्टम में उपयोगकर्ता पंजीकरण के संगठन और सिस्टम में उनके प्रवेश के संगठन पर विचार किया जाता है। यह JWT प्रौद्योगिकी और उपयोगकर्ता प्रतिरूपण के साथ काम करने जैसे मुद्दों को उठाएगा।

इसके अलावा,
इस GitHub रिपॉजिटरी पर ध्यान दें, जिसमें Node.js प्रोजेक्ट के लिए कोड है, जिसके कुछ उदाहरण इस लेख में दिए गए हैं। आप अपने स्वयं के प्रयोगों के आधार के रूप में इस भंडार का उपयोग कर सकते हैं।
परियोजना की आवश्यकताएं
यहां उस परियोजना के लिए आवश्यकताएं हैं जो हम यहां से निपटेंगे:
- एक डेटाबेस की उपस्थिति जिसमें उपयोगकर्ता का ईमेल पता और पासवर्ड संग्रहीत किया जाएगा, या तो क्लाइंटआईड और क्लायंटसेक्रेट, या निजी और सार्वजनिक कुंजी के संयोजन की तरह कुछ।
- पासवर्ड को एन्क्रिप्ट करने के लिए एक मजबूत और कुशल क्रिप्टोग्राफिक एल्गोरिथ्म का उपयोग करना।
फिलहाल जब मैं यह सामग्री लिख रहा हूं, मेरा मानना है कि उपलब्ध सर्वश्रेष्ठ क्रिप्टोग्राफिक एल्गोरिथ्म आर्गन 2 है। मैं आपसे SHA256, SHA512 या MD5 जैसे सरल क्रिप्टोग्राफ़िक एल्गोरिदम का उपयोग नहीं करने के लिए कहता हूं।
इसके अलावा, मेरा सुझाव है कि आप
इस अद्भुत सामग्री पर एक नज़र डालें, जिसमें आप हैशिंग पासवर्ड के लिए एक एल्गोरिथ्म चुनने के बारे में विवरण पा सकते हैं।
सिस्टम में उपयोगकर्ताओं का पंजीकरण
जब एक नया उपयोगकर्ता सिस्टम में बनाया जाता है, तो उसका पासवर्ड हैशेड होना चाहिए और डेटाबेस में संग्रहीत होना चाहिए। पासवर्ड को डेटाबेस में ईमेल पते और उपयोगकर्ता के बारे में अन्य जानकारी के साथ संग्रहीत किया जाता है (उदाहरण के लिए, उनमें से उपयोगकर्ता प्रोफ़ाइल, पंजीकरण समय और इसी तरह) हो सकता है।
import * as argon2 from 'argon2'; class AuthService { public async SignUp(email, password, name): Promise<any> { const passwordHashed = await argon2.hash(password); const userRecord = await UserModel.create({ password: passwordHashed, email, name, }); return {
उपयोगकर्ता खाते की जानकारी निम्नलिखित की तरह दिखनी चाहिए।
उपयोगकर्ता डेटा Robo3T का उपयोग करके MongoDB से पुनर्प्राप्त किया गयाउपयोगकर्ता लॉगिन
जब उपयोगकर्ता लॉग इन करने का प्रयास करता है, तो यहां की जाने वाली क्रियाओं का आरेख होता है।
उपयोगकर्ता लॉगिनयहां तब होता है जब कोई उपयोगकर्ता लॉग इन करता है:
- क्लाइंट सर्वर को सार्वजनिक पहचानकर्ता और उपयोगकर्ता की निजी कुंजी का संयोजन भेजता है। यह आमतौर पर एक ईमेल एड्रेस और पासवर्ड होता है।
- सर्वर डेटाबेस में उपयोगकर्ता को ईमेल पते द्वारा खोजता है।
- यदि उपयोगकर्ता डेटाबेस में मौजूद है, तो सर्वर उसके पास भेजे गए पासवर्ड को हैश करता है और डेटाबेस में संग्रहीत पासवर्ड हैश के साथ जो हुआ है उसकी तुलना करता है।
- यदि सत्यापन सफल होता है, तो सर्वर एक तथाकथित टोकन या प्रमाणीकरण टोकन उत्पन्न करता है - JSON वेब टोकन (JWT)।
JWT एक अस्थायी कुंजी है। क्लाइंट को यह कुंजी सर्वर को प्रत्येक अनुरोध के साथ प्रमाणित समापन बिंदु पर भेजनी होगी।
import * as argon2 from 'argon2'; class AuthService { public async Login(email, password): Promise<any> { const userRecord = await UserModel.findOne({ email }); if (!userRecord) { throw new Error('User not found') } else { const correctPassword = await argon2.verify(userRecord.password, password); if (!correctPassword) { throw new Error('Incorrect password') return { user: { email: userRecord.email, name: userRecord.name, }, token: this.generateJWT(userRecord), }
पासवर्ड सत्यापन आर्गन 2 लाइब्रेरी का उपयोग करके किया जाता है। यह तथाकथित "
समय हमलों " को रोकने के लिए है। इस तरह के हमले को करते समय, एक हमलावर को क्रूर बल द्वारा पासवर्ड को क्रैक करने की कोशिश की जाती है, जो इस बात के विश्लेषण के आधार पर होता है कि सर्वर को प्रतिक्रिया बनाने के लिए कितना समय चाहिए।
अब बात करते हैं कि JWT कैसे जेनरेट करें।
JWT क्या है?
JSON वेब टोकन (JWT) स्ट्रिंग रूप में एन्कोड किया गया JSON ऑब्जेक्ट है। कुकीज़ को कुकीज़ के विकल्प के रूप में लिया जा सकता है, जिसके कई फायदे हैं।
टोकन में तीन भाग होते हैं। यह शीर्ष लेख, पेलोड और हस्ताक्षर है। निम्नलिखित आंकड़ा इसकी उपस्थिति को दर्शाता है।
जेडब्ल्यूटीएक गुप्त कुंजी या हस्ताक्षर के उपयोग के बिना क्लाइंट डेटा पर टोकन डेटा को डिकोड किया जा सकता है।
यह स्थानांतरण के लिए उपयोगी हो सकता है, उदाहरण के लिए, टोकन के अंदर मेटाडेटा एन्कोडेड। इस तरह के मेटाडेटा उपयोगकर्ता की भूमिका, उसकी प्रोफ़ाइल, टोकन की अवधि और इसी तरह का वर्णन कर सकते हैं। उनका उपयोग फ्रंट-एंड एप्लिकेशन में उपयोग के लिए किया जा सकता है।
यहां एक डिकोडेड टोकन जैसा दिख सकता है।
डिकोडेड टोकनNW.js में JWT उत्पन्न करना
आइए
generateToken
फ़ंक्शन को
generateToken
हैं जिसे हमें उपयोगकर्ता प्रमाणीकरण सेवा पर काम पूरा करने की आवश्यकता है।
आप jsonwebtoken लाइब्रेरी का उपयोग करके JWT बना सकते हैं। इस लाइब्रेरी को आप npm में पा सकते हैं।
import * as jwt from 'jsonwebtoken' class AuthService { private generateToken(user) { const data = { _id: user._id, name: user.name, email: user.email }; const signature = 'MySuP3R_z3kr3t'; const expiration = '6h'; return jwt.sign({ data, }, signature, { expiresIn: expiration }); }
यहां सबसे महत्वपूर्ण बात एन्कोडेड डेटा है। टोकन में गुप्त उपयोगकर्ता जानकारी न भेजें।
एक हस्ताक्षर (यहाँ
signature
स्थिरांक है) गुप्त डेटा है जो JWT उत्पन्न करने के लिए उपयोग किया जाता है। यह सुनिश्चित करना बहुत महत्वपूर्ण है कि हस्ताक्षर गलत हाथों में न पड़ें। यदि हस्ताक्षर से समझौता किया जाता है, तो हमलावर उपयोगकर्ताओं की ओर से टोकन बनाने और उनके सत्रों को चोरी करने में सक्षम होगा।
समापन बिंदु सुरक्षा और JWT सत्यापन
अब क्लाइंट कोड को एक सुरक्षित समापन बिंदु के लिए हर अनुरोध में एक JWT भेजने की आवश्यकता है।
यह अनुशंसा की जाती है कि आप अनुरोध हेडर में JWT को शामिल करें। वे आमतौर पर प्राधिकरण हेडर में शामिल होते हैं।
प्राधिकरण के हेडरअब, सर्वर पर, आपको कोड बनाने की आवश्यकता है जो एक्सप्रेस मार्गों के लिए मिडलवेयर है। इस कोड को
isAuth.ts
फ़ाइल में रखें:
import * as jwt from 'express-jwt';
डेटाबेस से उपयोगकर्ता खाते के बारे में पूरी जानकारी प्राप्त करने और उन्हें अनुरोध में संलग्न करने में सक्षम होना उपयोगी है। हमारे मामले में, यह सुविधा
attachCurrentUser.ts
से
attachCurrentUser.ts
का उपयोग करके लागू की
attachCurrentUser.ts
है। फ़ाइल। यहाँ इसका सरलीकृत कोड है:
export default (req, res, next) => { const decodedTokenData = req.tokenData; const userRecord = await UserModel.findOne({ _id: decodedTokenData._id }) req.currentUser = userRecord; if(!userRecord) { return res.status(401).end('User not found') } else { return next(); }
इस तंत्र को लागू करने के बाद, मार्ग अनुरोध को निष्पादित करने वाले उपयोगकर्ता के बारे में जानकारी प्राप्त करने में सक्षम होंगे:
import isAuth from '../middlewares/isAuth'; import attachCurrentUser from '../middlewares/attachCurrentUser'; import ItemsModel from '../models/items'; export default (app) => { app.get('/inventory/personal-items', isAuth, attachCurrentUser, (req, res) => { const user = req.currentUser; const userItems = await ItemsModel.find({ owner: user._id }); return res.json(userItems).status(200); })
inventory/personal-items
मार्ग अब संरक्षित है। इसे एक्सेस करने के लिए, उपयोगकर्ता के पास एक वैध JWT होना चाहिए। एक मार्ग, इसके अतिरिक्त, उपयोगकर्ता जानकारी का उपयोग डेटाबेस की खोज के लिए कर सकता है।
घुसपैठियों से टोकन सुरक्षित क्यों हैं?
JWT का उपयोग करने के बारे में पढ़ने के बाद, आप अपने आप से निम्नलिखित प्रश्न पूछ सकते हैं: "यदि JWT डेटा क्लाइंट साइड पर डिकोड किया जा सकता है, तो क्या इस तरह से टोकन को संसाधित करना संभव है जैसे कि उपयोगकर्ता आईडी या अन्य डेटा को बदलना है?"।
टोकन डिकोडिंग - ऑपरेशन बहुत सरल है। हालाँकि, आप इस टोकन को उस हस्ताक्षर के बिना "फिर से" नहीं कर सकते, वह गुप्त डेटा जिसका उपयोग सर्वर पर JWT को साइन करते समय किया गया था।
यही कारण है कि इस संवेदनशील डेटा की सुरक्षा इतनी महत्वपूर्ण है।
हमारा सर्वर isAuth मिडलवेयर में हस्ताक्षर की पुष्टि करता है। एक्सप्रेस-jwt लाइब्रेरी जाँच के लिए ज़िम्मेदार है।
अब, जब हमें पता चला कि JWT तकनीक कैसे काम करती है, तो आइए कुछ दिलचस्प अतिरिक्त विशेषताओं के बारे में बात करते हैं जो हमें देती हैं।
उपयोगकर्ता को कैसे लगाया जाए?
उपयोगकर्ता प्रतिरूपण एक ऐसी प्रणाली है जिसका उपयोग किसी सिस्टम में एक विशिष्ट उपयोगकर्ता के रूप में अपना पासवर्ड जाने बिना किया जाता है।
यह सुविधा सुपर एडमिनिस्ट्रेटर्स, डेवलपर्स या सपोर्ट स्टाफ के लिए बहुत उपयोगी है। प्रतिरूपण उन्हें उन समस्याओं को हल करने की अनुमति देता है जो केवल सिस्टम के साथ काम करने वाले उपयोगकर्ताओं के पाठ्यक्रम में दिखाई देती हैं।
आप उसके पासवर्ड को जाने बिना उपयोगकर्ता की ओर से आवेदन के साथ काम कर सकते हैं। ऐसा करने के लिए, सही हस्ताक्षर के साथ और उपयोगकर्ता का वर्णन करने वाले आवश्यक मेटाडेटा के साथ एक JWT उत्पन्न करना पर्याप्त है।
एक अंतिम बिंदु बनाएँ जो विशिष्ट उपयोगकर्ताओं की आड़ में सिस्टम में प्रवेश करने के लिए टोकन उत्पन्न कर सकता है। केवल सिस्टम का सुपर-प्रशासक इस समापन बिंदु का उपयोग कर सकता है।
शुरुआत के लिए, हमें इस उपयोगकर्ता को अन्य उपयोगकर्ताओं की तुलना में उच्च विशेषाधिकार स्तर के साथ एक भूमिका सौंपने की आवश्यकता है। यह कई अलग-अलग तरीकों से किया जा सकता है। उदाहरण के लिए, केवल डेटाबेस में संग्रहीत उपयोगकर्ता जानकारी के लिए
role
क्षेत्र को जोड़ना।
यह नीचे दिखाए गए की तरह लग सकता है।
उपयोगकर्ता जानकारी में नया क्षेत्रsuper-admin
role
फील्ड का मान
super-admin
।
अगला, आपको एक नया मिडलवेयर बनाने की आवश्यकता है जो उपयोगकर्ता की भूमिका की जाँच करता है:
export default (requiredRole) => { return (req, res, next) => { if(req.currentUser.role === requiredRole) { return next(); } else { return res.status(401).send('Action not allowed'); }
यह IsAuth और संलग्नक के बाद रखा जाना चाहिए। अब अंतिम बिंदु बनाएं जो उस उपयोगकर्ता के लिए JWT उत्पन्न करता है, जिसकी ओर से सुपर-एडमिनिस्ट्रेटर लॉग इन करना चाहता है:
import isAuth from '../middlewares/isAuth'; import attachCurrentUser from '../middlewares/attachCurrentUser'; import roleRequired from '../middlwares/roleRequired'; import UserModel from '../models/user'; export default (app) => { app.post('/auth/signin-as-user', isAuth, attachCurrentUser, roleRequired('super-admin'), (req, res) => { const userEmail = req.body.email; const userRecord = await UserModel.findOne({ email: userEmail }); if(!userRecord) { return res.status(404).send('User not found'); return res.json({ user: { email: userRecord.email, name: userRecord.name }, jwt: this.generateToken(userRecord) }) .status(200); })
जैसा कि आप देख सकते हैं, रहस्यमय कुछ भी नहीं है। सुपर एडमिनिस्ट्रेटर को उस उपयोगकर्ता का ईमेल पता पता होता है, जिसकी ओर से आप लॉग इन करना चाहते हैं। उपरोक्त कोड का तर्क बहुत याद दिलाता है कि कोड कैसे काम करता है, आम उपयोगकर्ताओं की प्रणाली को एक इनपुट प्रदान करता है। मुख्य अंतर यह है कि यहां पासवर्ड की जांच नहीं की जाती है।
पासवर्ड को इस तथ्य के कारण सत्यापित नहीं किया गया है कि यहां बस इसकी आवश्यकता नहीं है। एंडपॉइंट सुरक्षा मिडलवेयर द्वारा प्रदान की जाती है।
परिणाम
तीसरे पक्ष के प्रमाणीकरण सेवाओं और पुस्तकालयों पर भरोसा करने में कुछ भी गलत नहीं है। इससे डेवलपर्स को समय बचाने में मदद मिलती है। लेकिन उन्हें उन सिद्धांतों के बारे में भी जानना होगा जिन पर प्रमाणीकरण प्रणालियों का संचालन आधारित है, और जो इस तरह के सिस्टम के कामकाज को सुनिश्चित करता है।
इस लेख में, हमने JWT प्रमाणीकरण की संभावनाओं का पता लगाया, हैशिंग पासवर्ड के लिए एक अच्छा क्रिप्टोग्राफ़िक एल्गोरिथम चुनने के महत्व के बारे में बात की। हमने एक उपयोगकर्ता प्रतिरूपण तंत्र के निर्माण की जांच की।
पासपोर्ट जैसी कुछ चीज़ों के साथ एक ही काम करना आसान है। प्रमाणीकरण एक बहुत बड़ा विषय है। शायद हम उसके पास लौट आएंगे।
प्रिय पाठकों! आप अपनी Node.js परियोजनाओं के लिए प्रमाणीकरण प्रणाली कैसे बनाते हैं?