2012-05-15 77 views
1

我想通過socketIO通過MySQL數據庫進行身份驗證。我建立了連接並可以查詢結果而沒有問題,但由於某種原因,我無法通過用戶是否被認證到socketio的connection部分。這個想法是我的應用程序有主持人和觀衆。如果連接到應用程序時未在QueryString中發送密碼,則該應用程序假定其爲查看器並接受連接。如果發送密碼,則會對數據庫進行檢查並接受/拒絕連接。我想要一個變量傳入connection,這樣我就可以在我的應用程序事件中使用它。以下是我目前爲止的內容,但顯然data.query['ishost']沒有傳入應用。SocketIO + MySQL身份驗證

sio.configure(function() { 
    sio.set('authorization', function (data, accept) { 
     UserID = data.query['username']; 

     try { 
      UserID = UserID.toLowerCase(); 
     } catch(err) { 
      return accept("No WebBot Specified. ("+err+")", false); 
     } 

     // if not sending a password, skip authorization and connect as a viewer 
     if (data.query['password'] === 'undefined') 
     { 
      return accept(null, true); 
     } 
     // if sending a password, attempt authorization and connect as a host 
     else 
     { 
      client.query(
      'SELECT * FROM web_users WHERE username = "'+UserID+'" LIMIT 1', 
       function selectCb(err, results, fields) { 
       if (err) { 
        throw err; 
       } 
       // Found match, hash password and check against DB 
       if (results.length != 0) 
       { 
        // Passwords match, authenticate. 
        if (hex_md5(data.query['password']) == results[0]['password']) 
        { 
         data.query['ishost'] = true; 
         accept(null, true); 
        } 
        // Passwords don't match, do not authenticate 
        else 
        { 
         data.query['ishost'] = false; 
         return accept("Invalid Password", false); 
        } 
       } 
       // No match found, add to DB then authenticate 
       else 
       { 
        client.query(
         'INSERT INTO web_users (username, password) VALUES ("'+UserID+'", "'+hex_md5(data.query['password'])+'")', null); 

        data.query['ishost'] = "1"; 
        accept(null, true); 
       } 

       client.end(); 
       } 
      ); 

      // Should never reach this 
      return accept("Hacking Attempt", false); 
     } 

     // Definitely should never reach this 
     return accept("Hacking Attempt", false); 
    }); 
}); 

寫入data.query使其可通過handshakeData訪問。但由於某種原因,它沒有通過應用程序傳遞。任何幫助表示讚賞,謝謝。

回答

5

你很近,但我建議設置一個請求頭來設置查詢字符串參數。授權功能中的data變量是握手數據,其中包含您可以使用的請求標頭和Cookie信息。下面是與設置cookie的例子:

在服務器

io.configure(function() { 
    io.set('authorization', function(handshake, callback) { 
     var cookie, token, authPair, parts; 

     // check for headers 
     if (handshake.headers.cookie && 
      handshake.headers.cookie.split('=')[0]=='myapp') { 

      // found request cookie, parse it 
      cookie = handshake.headers.cookie; 
      token = cookie.split(/\s+/).pop() || ''; 
      authPair = new Buffer(token, 'base64').toString(); 
      parts = authPair.split(/:/); 

      if (parts.length>=1) { 
       // assume username & pass provided, check against db 
       // parts[0] is username, parts[1] is password 
       // .... {db checks}, then if valid.... 
       callback(null, true); 
      } else if(parts.length==1) { 
       // assume only username was provided @ parts[0] 
       callback(null,true); 
      } else { 
       // not what we were expecting 
       callback(null, false); 
      } 
     } 
     else { 
      // auth failed 
      callback(null, false); 
     } 
    }); 
}); 

在客戶

你叫socket.connect之前,請設置您的身份驗證/用戶信息一個cookie:

function writeCookie(value, days) { 
    var date, expires; 

    // days indicates how long the user's session should last 
    if (days) { 
     date = new Date(); 
     date.setTime(date.getTime()+(days*24*60*60*1000)); 
     expires = "; expires="+date.toGMTString(); 
    } else { 
     expires = ""; 
    } 
    document.cookie = "myapp="+Base64.encode(value)+expires+"; path=/"; 
}; 

// for a 'viewer' user: 
writeCookie('usernameHere', 1); 

// for the 'host' user: 
writeCookie('usernameHere:passwordHere', 1); 

除非您的瀏覽器支持btoa(),否則您需要客戶端的Base64庫。

重要的是要指出,這不是一個好的身份驗證結構。直接在查詢字符串或標題信息中傳遞用戶憑證是不安全的。不過,這種方法讓你更接近更安全的方法。我建議尋找像passport.js或everyauth這樣的auth庫。您可以在此代碼中使用這些庫在運行檢查時存儲的會話信息。

+0

很好用。我會看看passport.js。謝謝你的幫助。 –

+0

如果你回退到閃存套接字,這個工作會嗎? – NightWolf

+0

我不確定,我通常會避免使用Flash套接字來簡化我的服務器配置 –