اذهب إلى المحتوى

السؤال

نشر

اريد ارسال كود تفعل للمستخدم عن طريق الايميل عند انشائي لهذا الكود اريد تخزينه ثم ارساله للمستخدم لكي اقارن الكود الذي تم ادخاله مع الكود الذي تم انشائه ، سؤالي هو كيف اخزن هذا الكود تخزين مؤقت ثم بعد ذلك حذفه ؟ قمت بتجربة ان اخزنه في متغير لكن شعرت انها ليست طريقة امنة هل هناك طريقة افضل ؟

Recommended Posts

  • 0
نشر

عند إنشاء حساب جديد، تقوم بإنشاء Token لها مدة زمنية و ترسلها مع البريد الإلكتروني مع الرابط، وعند نقر المستخدم عليه يطلب نفس الرابط من المخدم

مثلاً

http://server/verifyEmail/123456wael000afshgdf..

فيقوم بتفعل الحساب المرتبط مع هذه ال Token.

عند إنشاء الحساب:

//في متحكم إضافة المستخدم

router.post('/AddUser', function(req, res, next) {


// جلب بيانات المستخدم
var user = new User();
    user.name = req.body.name;
    user.email = req.body.email;
    user.is_verified = false;      // غير مفعل بعد

// جزء المصداقة

var info = {};
info.user = user;
// صلاحية
info.expiry = new Date(new Date().getTime() + 24 * 60 * 60 * 1000); 
// توليد Token
var token = jwt.encode(info,config.secret);
console.log("http://localhost:3000/verifyEmail/" + token);

// بيانات البريد الالكتروني
var mailOptions = {
  from : "TEST<noreply@vysly.com>",
  to : user.email,
  subject : "Welcome to TEST",
  text : 'Visit this http://localhost:3000/verifyEmail/'+token,
  html : '<a href="http://localhost:3000/verifyEmail/'+token+'"><H2>Click on this</H2></a>'
}

// إرسال البريد
// تعريف الكائن
 var transport = mailer.createTransport({
   service : "Gmail",
   auth : {
     user : config.central_email,
     pass : config.central_email_password
   }
 });
// الإرسال
transport.sendMail(mailOptions,function(email_err,email_data){
  if(email_err){
    console.log(email_err);
    res.json(email_err);
  }else{
    console.log("Email is Sent");
    res.json({result : 1});
  }
});

التأكد من التفعيل:

// متحكم المصادقة
router.get('/verifyEmail/:token',function(req,res){
  
  // جلب بيانات الطلبية
    var token = req.params.token;
    var data = jwt.decode(token,config.secret);
    console.log(new Date(data.expiry));
    console.log(new Date());
  
  // تاريخ الصلاحية
  // نتأكد من أن التوكن ليست منتهية
    if(new Date(data.expiry) > new Date()){
        User.findOne({ _id : data.user._id, name : data.user.name })
            .exec(function(err,user){
            if(err){
                console.log(err);
                res.json(err);
            }else if(!user){
                console.log("User not found");
                res.json({error : "User not found"});
            }else{
                console.log("User found");
                user.is_verified = true;                            // هنا نعدل حالة المستخدم بوضع أنه مفعل
                user.save(function(update_err,update_data){
                    if(update_err){
                        console.log(update_err);
                        res.json(update_err);
                    }else{
                        console.log("Email is verified of user "+update_data._id);
                        res.json({result : 1});
                    }
                });
            }
        });
    }else{
        console.log("Link is expired");
        res.json({error : "Link is expired"});
    }
});

 

  • 0
نشر (معدل)
بتاريخ On 18‏/2‏/2022 at 22:53 قال Wael Aljamal:

عند إنشاء حساب جديد، تقوم بإنشاء Token لها مدة زمنية و ترسلها مع البريد الإلكتروني مع الرابط، وعند نقر المستخدم عليه يطلب نفس الرابط من المخدم

مثلاً


http://server/verifyEmail/123456wael000afshgdf..

فيقوم بتفعل الحساب المرتبط مع هذه ال Token.

عند إنشاء الحساب:


//في متحكم إضافة المستخدم

router.post('/AddUser', function(req, res, next) {


// جلب بيانات المستخدم
var user = new User();
    user.name = req.body.name;
    user.email = req.body.email;
    user.is_verified = false;      // غير مفعل بعد

// جزء المصداقة

var info = {};
info.user = user;
// صلاحية
info.expiry = new Date(new Date().getTime() + 24 * 60 * 60 * 1000); 
// توليد Token
var token = jwt.encode(info,config.secret);
console.log("http://localhost:3000/verifyEmail/" + token);

// بيانات البريد الالكتروني
var mailOptions = {
  from : "TEST<noreply@vysly.com>",
  to : user.email,
  subject : "Welcome to TEST",
  text : 'Visit this http://localhost:3000/verifyEmail/'+token,
  html : '<a href="http://localhost:3000/verifyEmail/'+token+'"><H2>Click on this</H2></a>'
}

// إرسال البريد
// تعريف الكائن
 var transport = mailer.createTransport({
   service : "Gmail",
   auth : {
     user : config.central_email,
     pass : config.central_email_password
   }
 });
// الإرسال
transport.sendMail(mailOptions,function(email_err,email_data){
  if(email_err){
    console.log(email_err);
    res.json(email_err);
  }else{
    console.log("Email is Sent");
    res.json({result : 1});
  }
});

التأكد من التفعيل:


// متحكم المصادقة
router.get('/verifyEmail/:token',function(req,res){
  
  // جلب بيانات الطلبية
    var token = req.params.token;
    var data = jwt.decode(token,config.secret);
    console.log(new Date(data.expiry));
    console.log(new Date());
  
  // تاريخ الصلاحية
  // نتأكد من أن التوكن ليست منتهية
    if(new Date(data.expiry) > new Date()){
        User.findOne({ _id : data.user._id, name : data.user.name })
            .exec(function(err,user){
            if(err){
                console.log(err);
                res.json(err);
            }else if(!user){
                console.log("User not found");
                res.json({error : "User not found"});
            }else{
                console.log("User found");
                user.is_verified = true;                            // هنا نعدل حالة المستخدم بوضع أنه مفعل
                user.save(function(update_err,update_data){
                    if(update_err){
                        console.log(update_err);
                        res.json(update_err);
                    }else{
                        console.log("Email is verified of user "+update_data._id);
                        res.json({result : 1});
                    }
                });
            }
        });
    }else{
        console.log("Link is expired");
        res.json({error : "Link is expired"});
    }
});

 

شكرا لك اخي لكن انا اريد ان ارسل رمز تفعيل لا ان يقوم المستخدم بالضغط على زر التفعيل ، كيف احقق هذا ؟ 

هذه ابعد نقطة توصلت اليها وهي ارسال الرمز .. (لا اعلم ان كانت امنة 100%)

exports.viaCode = (req,res) => {
  try {

    //انشاء كائن يحوي رقم عشوائي
    var payload ={
      number:randomNum (),
    }
     //انشاء توكين  
    const token = jwt.sign(payload, process.env.VERIFY_TOKEN , {expiresIn: '10m'}); 

    // تخزين التوكين في قاعدة البيانات 
    var user = new User ({
      emailToken: token,
      isVerified: false,
    })

    const newUser = user.save();
    
    //فك التشفير من التوكين 
    var decoded = decode(token);
  

    //محتويات البريد
    var userEmail = req.body.email
    var mailOption ={
      from: `"مرحبا" <${process.env.EMAIL}>`,
      to: userEmail,
      subject: 'رمز التحقق',
      html: `<p> ${decoded.number} رمز التحقق هو </p>`
    }

    //ارسال البريد
    transporter.sendMail(mailOption, function(error, info) {
      if(error) {
        console.log(error)
        res.status(500).send()
      }
      else {
        console.log('via email has been sent !')
        res.status(200).send();
      }
    })
  } catch (error) {
    console.log(error)
    res.status(500).send()
  }
}

 

تم التعديل في بواسطة Samer Alashqar
  • 0
نشر
بتاريخ 1 دقيقة مضت قال Samer Alashqar:

شكرا لك اخي لكن انا اريد ان ارسل رمز تفعيل لا ان يقوم المستخدم بالضغط على زر التفعيل ، كيف احقق هذا ؟ 

في الشيفرة التي ارفقتها لك، يتم وضع رابط في الإيميل، استبدل الرابط بالنص الذي تريد إرساله. وأنت قمت بذلك، حسنا بقي لك فك تشفير Token و قراءة الرمز المولد عشوائيا ولكن طريقة الToken لا تحفظ الرمز في المخدم لذلك:

إن كنت تريد حفظ الرمز في المخدم، استخدم session storage و قم بضبط المدة الزمنية التي تناسبك للاحتفاظ ببيانات الجلسة. و عملية التحقق تتم من خلال التأكد هل الرمز الذي أدخله المستخدم موجود في session storage طبعا هذه في المخدم و ليس المتصفح

  • 0
نشر (معدل)
بتاريخ 6 ساعات قال Wael Aljamal:

في الشيفرة التي ارفقتها لك، يتم وضع رابط في الإيميل، استبدل الرابط بالنص الذي تريد إرساله. وأنت قمت بذلك، حسنا بقي لك فك تشفير Token و قراءة الرمز المولد عشوائيا ولكن طريقة الToken لا تحفظ الرمز في المخدم لذلك:

إن كنت تريد حفظ الرمز في المخدم، استخدم session storage و قم بضبط المدة الزمنية التي تناسبك للاحتفاظ ببيانات الجلسة. و عملية التحقق تتم من خلال التأكد هل الرمز الذي أدخله المستخدم موجود في session storage طبعا هذه في المخدم و ليس المتصفح

 

لماذا لا استطيع ان احفظ Token في قاعدة البيانات و اعطيه مدة زمنية ثم عند تفعيل الرمز من قبل المستخدم اقوم بحذف Token من قاعدة البيانات و اقوم بتعديل 

      isVerified: false;

الى: 

      isVerified: true;

اليست هذه الطريقة ابسط ؟

تم التعديل في بواسطة Samer Alashqar
  • 0
نشر
بتاريخ 6 ساعات قال Samer Alashqar:

 

لماذا لا استطيع ان احفظ Token في قاعدة البيانات و اعطيه مدة زمنية ثم عند تفعيل الرمز من قبل المستخدم اقوم بحذف Token من قاعدة البيانات و اقوم بتعديل 


      isVerified: false;

الى: 


      isVerified: true;

اليست هذه الطريقة ابسط ؟

هي طريقة ممكنة، لكن من الممكن عدم إكمال المستخدم تسجيل الدخول، أو محاولته الدخول أكثر من مرة بشكل خاطئ ما يملأ قواعد البيانات بدون نفع، مما يضطرك لعمل دالة تحذف البيانات منتهية الصلاحية من القاعدة.. لذلك Token هو أفضل حل، يليه تخزين الجلسة لأنه يحذف بطريقة تلقائية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...