पासवर्ड रीसेट कैसे करें?


81

मैं ASP.NET में एक एप्लिकेशन पर काम कर रहा हूं, और विशेष रूप से सोच रहा था कि Password Resetअगर मैं अपना रोल करना चाहता हूं तो मैं एक फ़ंक्शन कैसे लागू कर सकता हूं।

विशेष रूप से, मेरे पास निम्नलिखित प्रश्न हैं:

  • यूनिक आईडी जनरेट करने का एक अच्छा तरीका क्या है जो क्रैक करना मुश्किल है?
  • क्या इसमें टाइमर लगा होना चाहिए? यदि हां, तो यह कब तक होना चाहिए?
  • क्या मुझे आईपी एड्रेस रिकॉर्ड करना चाहिए? क्या इससे भी फर्क पड़ता है?
  • "पासवर्ड रीसेट" स्क्रीन के तहत मुझे क्या जानकारी मांगनी चाहिए? बस ईमेल पता? या हो सकता है कि ईमेल पता और जानकारी के कुछ टुकड़े जो उन्हें 'पता' हो? (पसंदीदा टीम, पिल्ला का नाम, आदि)

क्या कोई अन्य विचार हैं जिनसे मुझे अवगत होने की आवश्यकता है?

NB : अन्य प्रश्न पूरी तरह से तकनीकी कार्यान्वयन पर चमक गए हैं । वास्तव में स्वीकार किए गए उत्तर ग्लोरी विवरण से अधिक चमकते हैं। मुझे उम्मीद है कि यह सवाल और बाद के जवाबों को विवरण में जाना जाएगा, और मुझे उम्मीद है कि इस सवाल को और अधिक संकरा करके फिर से जवाब दिया जाएगा कि उत्तर कम 'फुलाना' और अधिक 'गोर' हैं।

संपादित करें : ऐसे तालिका में मॉडल तालिका और SQL सर्वर या किसी ASP.NET MVC लिंक को कैसे संभाला जाएगा, इस पर भी उत्तर की सराहना की जाएगी।


ASP.NET MVC डिफ़ॉल्ट ASP.NET प्रमाणीकरण प्रदाता का उपयोग करता है, इसलिए आपके द्वारा उस sshould के आस-पास मिलने वाले किसी भी कोड नमूने को आपके उद्देश्यों के लिए प्रासंगिक होना चाहिए।
पौलविट

जवाबों:


66

यहाँ बहुत सारे अच्छे उत्तर हैं, मैं यह सब दोहराना नहीं चाहता हूँ ...

एक मुद्दे को छोड़कर, जो लगभग हर उत्तर द्वारा दोहराया जाता है, भले ही वह गलत हो:

अनुमान (वास्तविक) अद्वितीय और सांख्यिकीय रूप से अनुमान लगाने में असंभव हैं।

यह सच नहीं है, GUID बहुत कमजोर पहचानकर्ता हैं, और इसका उपयोग उपयोगकर्ता के खाते तक पहुंच की अनुमति के लिए नहीं किया जाना चाहिए ।
यदि आप संरचना की जांच करते हैं, तो आपको अधिकतम 128 बिट्स मिलते हैं ... जो आजकल बहुत अधिक नहीं माना जाता है।
जिसमें से पहली छमाही ठेठ अपरिवर्तनीय (जनरेटिंग सिस्टम के लिए) है, और जो शेष बचा है उसका आधा समय-निर्भर (या कुछ और समान) है।
सब सब में, इसकी एक बहुत कमजोर और आसानी से भंगुर तंत्र।

तो उस का उपयोग न करें!

इसके बजाय, केवल एक क्रिप्टोग्राफिक रूप से मजबूत यादृच्छिक संख्या जनरेटर ( System.Security.Cryptography.RNGCryptoServiceProvider) का उपयोग करें, और कम से कम 256 बिट कच्चे एन्ट्रापी प्राप्त करें।

सभी बाकी, कई अन्य जवाब के रूप में प्रदान की।


6
बिल्कुल सहमत हूं, जहां तक ​​मुझे पता है, GUID को कभी भी क्रिप्टोग्राफिक रूप से मजबूत और अनुमान लगाने में असंभव नहीं बनाया गया था।
Jan Soltis 7

5
अच्छी तरह से कहा, AFAIK MSDN स्पष्ट रूप से कहता है कि GUID का उपयोग सुरक्षा के लिए नहीं किया जाना चाहिए।
डॉ।

2
संस्करण 4 यूयूआईडी 2000 से विंडोज में उपयोग किया जाता है: .NET 4 GUID कैसे उत्पन्न होते हैं? - ढेर अतिप्रवाह । उनके पास 122 यादृच्छिक बिट्स हैं, जो मुझे लगता है कि एनआईएसटी सिफारिशों के अनुरूप है। एक स्थानीय हमले के लिए बहुत खराब भेद्यता थी, जो कि क्रिप्टगेनजैंड्रैम के अनुसार - विकिपीडिया को 2008 तक विस्टा और एक्सपी में तय किया गया था। इसलिए आपको GUID के वर्तमान उपयोग में समस्याएँ कहाँ दिखाई देती हैं?
nealmcb

4
वह "ओल्ड न्यू थिंग" ब्लॉग एके संस्करण 1 यूयूआईडी का वर्णन कर रहा है, और एक इंटरनेट ड्राफ्ट का उल्लेख करता है (कुछ ऐसा जिसे आप कभी नहीं करना चाहिए) जो 1998 में ब्लॉग पोस्ट से 10 साल पहले समाप्त हो गया था। मुझे भविष्य में उन पर संदेह होगा। हमने उन लड़ाइयों को बहुत पहले लड़ा था, और लगता है कि उनमें से अधिकांश जीत गई हैं। मैं अभी भी सहमत हूं कि क्रिप्टो-रैंडम स्रोत के लिए एक साफ एपीआई कॉल का उपयोग करना बेहतर है, लेकिन संस्करण 4 में GUID / UUIDs पर इतना कठिन नहीं है।
nealmcb

1
इसके लायक क्या है, यह सवाल का जवाब नहीं देता है, "पासवर्ड कैसे रीसेट करें"। आपने बस GUIDs के बारे में शानदार बातें बताईं।
रेक्स व्हीट जूल

67

EDIT 2012/05/22: इस लोकप्रिय उत्तर के अनुवर्ती के रूप में, मैं अब इस प्रक्रिया में स्वयं GUID का उपयोग नहीं करता। अन्य लोकप्रिय उत्तर की तरह, अब मैं URL में भेजने के लिए कुंजी उत्पन्न करने के लिए अपने स्वयं के हैशिंग एल्गोरिथ्म का उपयोग करता हूं। यह छोटा होने का भी फायदा है। उन्हें उत्पन्न करने के लिए System.Security.Cryptography में देखें, जिसे मैं आमतौर पर SALT के रूप में भी उपयोग करता हूं।

सबसे पहले, उपयोगकर्ता के पासवर्ड को तुरंत रीसेट न करें।

सबसे पहले, जब वे अनुरोध करते हैं, तो उपयोगकर्ता के पासवर्ड को तुरंत रीसेट न करें। यह एक सुरक्षा उल्लंघन है क्योंकि कोई व्यक्ति ईमेल पते (यानी कंपनी में आपका ईमेल पता) और व्हाट्सएप पर पासवर्ड रीसेट कर सकता है। इन दिनों की सर्वोत्तम प्रथाओं में आमतौर पर उपयोगकर्ता के ईमेल पते पर भेजा गया "पुष्टि" लिंक शामिल होता है, यह पुष्टि करता है कि वे इसे रीसेट करना चाहते हैं। यह लिंक वह है जहाँ आप अद्वितीय कुंजी लिंक भेजना चाहते हैं। मैं एक लिंक के साथ मेरा भेजने के लिए जैसे:domain.com/User/PasswordReset/xjdk2ms92

हां, लिंक पर एक टाइमआउट सेट करें और कुंजी और टाइमआउट को अपने बैकएंड पर स्टोर करें (और यदि आप एक का उपयोग कर रहे हैं तो नमक)। 3 दिनों का टाइमआउट आदर्श है, और जब वे रीसेट करने का अनुरोध करते हैं, तो वेब स्तर पर 3 दिनों के उपयोगकर्ता को सूचित करना सुनिश्चित करें।

एक अद्वितीय हैश कुंजी का उपयोग करें

मेरे पिछले उत्तर ने एक GUID का उपयोग करने के लिए कहा। अब मैं इसे संपादित कर रहा हूँ ताकि सभी को बेतरतीब ढंग से उत्पन्न हैश का उपयोग करने की सलाह दी जा सके, उदाहरण के लिए RNGCryptoServiceProvider। और, हैश से किसी भी "वास्तविक शब्द" को समाप्त करना सुनिश्चित करें। मुझे एक विशेष 6am फोन कॉल याद है, जहां एक महिला ने अपने "रैंडम होने का अनुमान" में एक "ग" शब्द प्राप्त किया था जो कि एक डेवलपर ने किया था। दोहे!

पूरी प्रक्रिया

  • उपयोगकर्ता "रीसेट" पासवर्ड पर क्लिक करता है।
  • उपयोगकर्ता को एक ईमेल के लिए कहा जाता है।
  • उपयोगकर्ता ईमेल में प्रवेश करता है और क्लिक भेजता है। ईमेल की पुष्टि या खंडन न करें क्योंकि यह बुरा अभ्यास भी है। सीधे शब्दों में कहें, "हमने ईमेल को सत्यापित करने पर पासवर्ड रीसेट अनुरोध भेजा है।" या कुछ और एक जैसे।
  • आप से एक हैश बनाते हैं RNGCryptoServiceProvider, इसे एक अलग इकाई के रूप में एक ut_UserPasswordRequestsतालिका में संग्रहीत करते हैं और उपयोगकर्ता को वापस लिंक करते हैं। इसलिए यह पुराने अनुरोधों को ट्रैक कर सकता है और उपयोगकर्ता को सूचित कर सकता है कि पुराने लिंक समाप्त हो चुके हैं।
  • ईमेल पर लिंक भेजें।

उपयोगकर्ता लिंक को पसंद करता है http://domain.com/User/PasswordReset/xjdk2ms92, और उसे क्लिक करता है।

यदि लिंक सत्यापित है, तो आप एक नया पासवर्ड मांगते हैं। सरल, और उपयोगकर्ता अपना पासवर्ड सेट करने के लिए हो जाता है। या, अपना स्वयं का गुप्त पासवर्ड यहां सेट करें और उन्हें अपने नए पासवर्ड की जानकारी यहां दें (और उन्हें यह ईमेल करें)।


1
आई वाज़ वंडरिंग, यदि वास्तविक उपयोगकर्ता पासवर्ड हैशेड है, तो एक नया एचएएसएच कुंजी क्यों उत्पन्न करें? हशेड पासवर्ड पास करने वाले पासवर्ड को रीसेट करने के लिए लिंक के साथ उपयोगकर्ता को एक ईमेल भेजने के लिए सही नहीं होगा? हैशेड पासवर्ड को वापस नहीं किया जा सकता है, जब उपयोगकर्ता लिंक पर क्लिक करता है, तो सर्वर हैशेड पासवर्ड प्राप्त करेगा, वास्तविक संग्रहीत के साथ तुलना करेगा, और फिर उपयोगकर्ता को पासवर्ड बदलने की अनुमति देगा।
डैनियल

और इसके बारे में एक और अच्छी बात यह है कि, आपको टाइमआउट सेट करने की आवश्यकता नहीं है, एक बार जब उपयोगकर्ता ने पासवर्ड बदल दिया है, तो पुराना लिंक स्वचालित रूप से किसी भी अधिक मान्य नहीं होगा, क्योंकि डेटाबेस में संग्रहीत हैशेड पासवर्ड को बदल दिया गया था।
डैनियल

@ डैनियल यह एक बहुत बुरा विचार है। मुझे लगता है कि आपको Google को "जानवर बल के हमलों" की आवश्यकता है। इसके अलावा, जिस कारण से आप इसे समाप्त करना चाहते हैं, यदि किसी के ईमेल में सड़क से नीचे एक वर्ष समझौता किया गया है (और वे इसे कभी भी रीसेट नहीं करते हैं), तो पासवर्ड बदलने के लिए हैकर को अधिकार मिल जाते हैं।
eduncan911

@ educationan911 मुझे पता है कि ब्रूट फोर्स के हमले, लेकिन यह भी कि हेस्ड कुंजी तक पहुंचने के लिए, खराब इरादे वाले व्यक्ति को ईमेल तक पहुंच है, और यदि उसके पास पहुंच है, तो हैशेड पासवर्ड को वापस करने की कोई आवश्यकता नहीं है। इसके अलावा, इसे लगभग असंभव बनाने के लिए, आप हैशेड पासवर्ड, या इससे भी बेहतर हैश को पासवर्ड के साथ कुछ और कर सकते हैं। मैं आपसे असहमत नहीं हूँ, मैं इसके बारे में सिर्फ एक मंथन करने की कोशिश कर रहा हूँ
डैनियल

8

सबसे पहले, हमें यह जानना होगा कि आप पहले से ही उपयोगकर्ता के बारे में क्या जानते हैं। जाहिर है, आपके पास एक उपयोगकर्ता नाम और एक पुराना पासवर्ड है। और क्या जानते हो? क्या आपका ई - मेल एड्रेस है? क्या आपके पास उपयोगकर्ता के पसंदीदा फूल के बारे में डेटा है?

यह मानते हुए कि आपके पास एक उपयोगकर्ता नाम, पासवर्ड और काम करने का ईमेल पता है, आपको अपनी उपयोगकर्ता तालिका में दो फ़ील्ड जोड़ने की आवश्यकता है (यह मानते हुए कि यह एक डेटाबेस तालिका है): new_passwd_expire नामक एक तारीख और एक स्ट्रिंग new_passwd_id।

यह मानते हुए कि आपके पास उपयोगकर्ता का ईमेल पता है, जब कोई व्यक्ति पासवर्ड रीसेट करने का अनुरोध करता है, तो आप उपयोगकर्ता तालिका को निम्नानुसार अपडेट करते हैं:

new_passwd_expire = now() + some number of days
new_passwd_id = some random string of characters (see below)

इसके बाद, आप उस पते पर उपयोगकर्ता को एक ईमेल भेजते हैं:

प्रिय-तो-और

किसी व्यक्ति ने उपयोगकर्ता खाते के लिए एक नया पासवर्ड का अनुरोध किया है <यूज़र> <अपनी वेबसाइट का नाम>। यदि आपने इस पासवर्ड रीसेट का अनुरोध किया है, तो इस लिंक का अनुसरण करें:

http://example.com/yourscript.lang?update= < new_password_id >

यदि वह लिंक काम नहीं करता है तो आप http://example.com/yourscript.lang पर जा सकते हैं और फॉर्म में निम्नलिखित दर्ज कर सकते हैं : <new_password_id>

यदि आपने पासवर्ड रीसेट का अनुरोध नहीं किया है, तो आप इस ईमेल को अनदेखा कर सकते हैं।

धन्यवाद, यदा यदा

अब, कोडिंग yourcript.lang: इस स्क्रिप्ट को एक फॉर्म की आवश्यकता है। यदि संस्करण अद्यतन URL पर पारित हो गया है, तो फ़ॉर्म केवल उपयोगकर्ता के उपयोगकर्ता नाम और ईमेल पते के लिए पूछता है। यदि अपडेट पारित नहीं हुआ है, तो यह उपयोगकर्ता नाम, ईमेल पता और ईमेल में भेजा गया आईडी कोड पूछता है। आप एक नया पासवर्ड (दो बार) भी मांगते हैं।

उपयोगकर्ता के नए पासवर्ड को सत्यापित करने के लिए, आप उपयोगकर्ता नाम, ईमेल पता, और आईडी कोड सभी मिलान सत्यापित करते हैं, कि अनुरोध समाप्त नहीं हुआ है, और यह कि दो नए पासवर्ड मेल खाते हैं। सफल होने पर, आप उपयोगकर्ता के पासवर्ड को नए पासवर्ड में बदलते हैं और उपयोगकर्ता तालिका से पासवर्ड रीसेट फ़ील्ड साफ़ करते हैं। साथ ही उपयोगकर्ता को लॉग आउट करना / किसी भी लॉगिन से संबंधित कुकीज़ को साफ़ करना सुनिश्चित करें और उपयोगकर्ता को लॉगिन पृष्ठ पर पुनः निर्देशित करें।

अनिवार्य रूप से, new_passwd_id फ़ील्ड एक पासवर्ड है जो केवल पासवर्ड रीसेट पेज पर काम करता है।

एक संभावित सुधार: आप ईमेल से <username> निकाल सकते हैं। "किसी ने इस ईमेल पते पर एक खाते के लिए एक पासवर्ड रीसेट का अनुरोध किया है ...." इस प्रकार उपयोगकर्ता कुछ बनाता है केवल उपयोगकर्ता जानता है कि क्या ईमेल अवरोधन है। मैंने इस तरह से शुरुआत नहीं की क्योंकि अगर कोई खाता पर हमला कर रहा है, तो वे पहले से ही उपयोगकर्ता नाम जानते हैं। यह जोड़ा अस्पष्टता मानव-में-बीच के अवसरों के हमलों को रोकती है, जब कोई दुर्भावनापूर्ण ईमेल को बाधित करने के लिए होता है।

अपने प्रश्नों के लिए:

रैंडम स्ट्रिंग जनरेट करना: यह बेहद रैंडम होने की जरूरत नहीं है। कोई भी GUID जनरेटर या यहां तक ​​कि md5 (कंकट (नमक, current_timestamp ())) पर्याप्त है, जहां उपयोगकर्ता के रिकॉर्ड पर नमक कुछ ऐसा है जैसे टाइमस्टैम्प खाता बनाया गया था। यह कुछ ऐसा है जो उपयोगकर्ता नहीं देख सकता है।

टाइमर: हाँ, आपको अपने डेटाबेस को सुरक्षित रखने के लिए इसकी आवश्यकता है। एक सप्ताह से अधिक वास्तव में आवश्यक नहीं है, लेकिन कम से कम 2 दिन के बाद से आप कभी नहीं जानते कि ईमेल में देरी कितनी देर तक हो सकती है।

आईपी ​​एड्रेस: ​​चूंकि ईमेल को दिनों तक देरी हो सकती है, आईपी एड्रेस केवल लॉगिंग के लिए उपयोगी है, सत्यापन के लिए नहीं। यदि आप इसे लॉग इन करना चाहते हैं, तो ऐसा करें, अन्यथा आपको इसकी आवश्यकता नहीं है।

स्क्रीन रीसेट करें: ऊपर देखें।

आशा है कि इसे कवर करता है। सौभाग्य।


क्या संभावित हमलावर वर्तमान डेटास्टैम्प के एमडी 5 का उपयोग करने में सक्षम नहीं होगा?
जॉर्ज स्टॉकर

मैं तार पर ईमेल में एक पासवर्ड भेजने के खिलाफ दृढ़ता से अनुशंसा करूंगा। अधिकांश उपयोगकर्ता इन ईमेलों को अनिर्धारित छोड़ देते हैं जो एक सुरक्षा उल्लंघन है - उनमें से कुछ हर बार अपने 'पसंदीदा' ईमेल से इसे कॉपी-पेस्ट करना पसंद करेंगे। क्या होगा यदि उपयोगकर्ता कंपनी मेल सर्वर का प्रमाणपत्र समाप्त हो गया है और यातायात सूँघा है? इस संभावित उल्लंघन को कम करने के लिए (1) इस विशेष पासवर्ड का एक छोटा समाप्ति समय निर्धारित करें - 1 घंटा, और (2) उपयोगकर्ता को अगले लॉग ऑन पर इसे अपडेट करने के लिए मजबूर करें।
ओग्यान दिमित्रोव

ओगयान, ईमेल में भेजा गया पासवर्ड केवल एक बार काम करता है। उन्हें लॉगिन के बाद अपना पासवर्ड बदलना होगा और ईमेल में उपयोगकर्ता लॉगिन नाम नहीं होगा। तो, नहीं, वे इसे हर बार कॉपी-पेस्ट नहीं कर सकते। ईमेल हटाना नहीं सुरक्षा मुद्दा नहीं है क्योंकि यह केवल अक्षरों / संख्याओं का एक अर्थहीन स्ट्रिंग है जो पासवर्ड रीसेट होने के बाद हमलावर NOTHING को प्राप्त करेगा।
jmucchiello

3

रिकॉर्ड के ईमेल पते पर भेजा गया एक GUID अधिकांश रन-ऑफ-द-मिल अनुप्रयोगों के लिए पर्याप्त है - टाइमआउट के साथ और भी बेहतर।

आखिरकार, अगर उपयोगकर्ता ईमेलबॉक्स से समझौता किया गया है (यानी एक हैकर के पास ईमेल पते के लिए लॉगऑन / पासवर्ड है), तो बहुत कुछ नहीं है जिसके बारे में आप कर सकते हैं।


2

आप एक लिंक के साथ उपयोगकर्ता को एक ईमेल भेज सकते हैं। इस लिंक में स्ट्रिंग का अनुमान लगाने के लिए कुछ कड़ी मेहनत होगी (जैसे GUID)। सर्वर साइड पर आप उसी स्ट्रिंग को भी स्टोर करेंगे जैसे आपने यूजर को भेजा था। अब जब उपयोगकर्ता लिंक पर प्रेस करता है तो आप अपनी डीबी प्रविष्टि में उसी गुप्त स्ट्रिंग के साथ पा सकते हैं और उसका पासवर्ड रीसेट कर सकते हैं।


अधिक जानकारी मददगार होगी।
जॉर्ज स्टॉकर

2

1) अद्वितीय आईडी बनाने के लिए आप सुरक्षित हैश एल्गोरिथ्म का उपयोग कर सकते हैं। 2) टाइमर संलग्न? क्या आपके पास रीसेट pwd लिंक के लिए एक एक्सपायरी है? हाँ, आपके पास एक एक्सपायरी सेट 3 हो सकता है) आप ईमेल आईडी के अलावा कुछ और जानकारी पूछ सकते हैं जिन्हें मान्य किया जा सके .. जैसे जन्म तिथि या कुछ सुरक्षा प्रश्न 4) आप यादृच्छिक अक्षर भी उत्पन्न कर सकते हैं और अनुरोध के साथ उसे दर्ज करने के लिए भी कह सकते हैं। .. यह सुनिश्चित करने के लिए कि पासवर्ड अनुरोध कुछ स्पाइवेयर या उस तरह की चीजों द्वारा स्वचालित नहीं है ..


0

मुझे लगता है कि ASP.NET पहचान के लिए Microsoft गाइड एक अच्छी शुरुआत है।

https://docs.microsoft.com/en-us/aspnet/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity

कोड जो मैं ASP.NET पहचान के लिए उपयोग करता हूं:

Web.Config:

<add key="AllowedHosts" value="example.com,example2.com" />

AccountController.cs:

[Route("RequestResetPasswordToken/{email}/")]
[HttpGet]
[AllowAnonymous]
public async Task<IHttpActionResult> GetResetPasswordToken([FromUri]string email)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    var user = await UserManager.FindByEmailAsync(email);
    if (user == null)
    {
        Logger.Warn("Password reset token requested for non existing email");
        // Don't reveal that the user does not exist
        return NoContent();
    }

    //Prevent Host Header Attack -> Password Reset Poisoning. 
    //If the IIS has a binding to accept connections on 80/443 the host parameter can be changed.
    //See https://security.stackexchange.com/a/170759/67046
    if (!ConfigurationManager.AppSettings["AllowedHosts"].Split(',').Contains(Request.RequestUri.Host)) {
            Logger.Warn($"Non allowed host detected for password reset {Request.RequestUri.Scheme}://{Request.Headers.Host}");
            return BadRequest();
    }

    Logger.Info("Creating password reset token for user id {0}", user.Id);

    var host = $"{Request.RequestUri.Scheme}://{Request.Headers.Host}";
    var token = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
    var callbackUrl = $"{host}/resetPassword/{HttpContext.Current.Server.UrlEncode(user.Email)}/{HttpContext.Current.Server.UrlEncode(token)}";

    var subject = "Client - Password reset.";
    var body = "<html><body>" +
               "<h2>Password reset</h2>" +
               $"<p>Hi {user.FullName}, <a href=\"{callbackUrl}\"> please click this link to reset your password </a></p>" +
               "</body></html>";

    var message = new IdentityMessage
    {
        Body = body,
        Destination = user.Email,
        Subject = subject
    };

    await UserManager.EmailService.SendAsync(message);

    return NoContent();
}

[HttpPost]
[Route("ResetPassword/")]
[AllowAnonymous]
public async Task<IHttpActionResult> ResetPasswordAsync(ResetPasswordRequestModel model)
{
    if (!ModelState.IsValid)
        return NoContent();

    var user = await UserManager.FindByEmailAsync(model.Email);
    if (user == null)
    {
        Logger.Warn("Reset password request for non existing email");
        return NoContent();
    }            

    if (!await UserManager.UserTokenProvider.ValidateAsync("ResetPassword", model.Token, UserManager, user))
    {
        Logger.Warn("Reset password requested with wrong token");
        return NoContent();
    }

    var result = await UserManager.ResetPasswordAsync(user.Id, model.Token, model.NewPassword);

    if (result.Succeeded)
    {
        Logger.Info("Creating password reset token for user id {0}", user.Id);

        const string subject = "Client - Password reset success.";
        var body = "<html><body>" +
                   "<h1>Your password for Client was reset</h1>" +
                   $"<p>Hi {user.FullName}!</p>" +
                   "<p>Your password for Client was reset. Please inform us if you did not request this change.</p>" +
                   "</body></html>";

        var message = new IdentityMessage
        {
            Body = body,
            Destination = user.Email,
            Subject = subject
        };

        await UserManager.EmailService.SendAsync(message);
    }

    return NoContent();
}

public class ResetPasswordRequestModel
{
    [Required]
    [Display(Name = "Token")]
    public string Token { get; set; }

    [Required]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 10)]
    [DataType(DataType.Password)]
    [Display(Name = "New password")]
    public string NewPassword { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm new password")]
    [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.