2016-03-02 55 views
2

任何人都可以幫助我解答用於從用戶輸入(電子郵件地址)創建安全標記(或散列)的方法。我想爲註冊製作一個電子郵件驗證系統。從用戶電子郵件創建用於電子郵件驗證的散列/標記

  • 用戶提供的電子郵件地址和密碼,
  • 登記我想創建,我會送出去給用戶(因此這個問題)
  • 唯一的URL我存儲這些(安全方面)在臨時表
  • 用戶通過發送出

我的問題是這樣的URL看起來應該像URL驗證自己。我想我應該通過將電子郵件地址編碼到它中來使它唯一,將url保存到臨時表中,當用戶打開鏈接時,我會比較兩者。如果匹配,我會將憑據移動到真正的表格。

關於這個話題你有什麼好的資源。我在後端有nodejs。謝謝

+0

'哈希(mailaddress + constantsalt)' – deviantfan

+1

謝謝,我不應該使用一個隨機鹽代替檢查EXPIRY_DATE? –

+0

您也可以使用每個用戶的隨機鹽。只要足夠長且足夠隨機以防止猜測,就沒有問題。 – deviantfan

回答

-2

爲什麼不是SHA1哈希?

var crypto = require('crypto');

var uString = crypto.createHash('sha1')。update('[email protected]')。digest('hex');

將爲每個唯一的電子郵件ID生成唯一的密鑰。您可以連接時間戳以進一步發送電子郵件。

編輯:正如在評論中提到

,因爲它僅使用公共信息創建哈希上面的方法是不是安全。因此:

var uString = crypto.createHash('sha1')。update('[email protected]'+ mySecretKey).digest('hex');

其中mySecretKey可以是隨機字符串,如果您的計劃不是在驗證過程中重新創建哈希。

+2

'爲什麼不使用SHA1哈希?'因爲只有郵件地址(和其他公共信息)的散列,用戶可能會輸入一個錯誤的郵件地址,然後進行確認。 – deviantfan

+0

用戶可能會輸入一個錯誤的郵件地址,並確認它?我在這裏不理解你,只有在郵件內部鏈接可用時,如何確認。 – Mannu

+2

用你的方法,用戶不需要帶鏈接的郵件,因爲他/她可以在家計算哈希令牌(它只包含用戶已知的信息和公知的算法),然後只需調用與它鏈接(沒有令牌的鏈接也不是祕密)。 – deviantfan

0

我認爲你的方法也是正確的。我在Express(REST API)中使用類似的方法完成了電子郵件驗證。我使用jsonwebtoken來編碼email_id,user_id和expiry_date(用於檢查在用戶註冊的電子郵件地址上發送的鏈接的有效性)。

然後追加該編碼數據鏈接 例:http://your_backend_server_link/verifyEmail/1234567890afshgdf ...

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; 

    user.save(function(err,user){ 
     if(err){ 
      console.log(err); 
      res.json(err); 
     } else{ 
      console.log("User data saved"); 

      var transport = mailer.createTransport({ 
       service : "Gmail", 
       auth : { 
        user : config.central_email, 
        pass : config.central_email_password 
       } 
      }); 

//   tommorow's date 
      var info = {}; 
      info.user = user; 
      info.expiry = new Date(new Date().getTime() + 24 * 60 * 60 * 1000); 
      var token = jwt.encode(info,config.secret); 
      console.log("http://localhost:3000/verifyEmail/" + token); 

      var mailOptions = { 
       from : "TEST<[email protected]>", 
       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>' 
      } 
      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}); 
       } 
      }); 

     } 
    }); 
}); 

當此鏈接的用戶點擊,也會從URL令牌和解碼。通過與服務器的當前日期比較鏈路的有效性

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"}); 
    } 
});