在 sql 中创建可以接受多个参数的存储过程

create stored procedure in sql which can take multiple arguments

我正在尝试使用 express.js 和 mysql 制作基本的 login/registration 系统。在第一个原型中,我使用字符串查询从数据库中输入和检索数据。现在我想升级它并使用存储过程,因为有人在 Whosebug 上告诉我,以字符串形式提供查询会使系统容易受到 sql 注入的攻击。我的查询包含用户通过注册或登录表单提供的两个参数。

这里是查询

    var username, password;
    var userInfoArray = [username, password]
    var registrationQueryString = "INSERT INTO userinfo (username, password) VALUES ( ?, ? )"
    var loginQueryString = "SELECT username, password FROM userinfo WHERE EXISTS (SELECT username, password FROM userinfo WHERE userinfo.username = ( ? ) AND userinfo.password = ( ? ))"
    
    function userRegistration (userInfoArray){
        dbConnection.query( registrationQueryString, userInfoArray, function(err, results, fields) {
            if (err) throw err
            console.log("registered new user")
        })
    }
    function userLogin (userInfoArray){
        dbConnection.query( loginQueryString, userInfoArray, function(err, results, fields) {
            if (err) throw err
            console.log(results)
        })
    }

我想让存储过程等同于我提供的代码。

关于同一个问题,我发现了太多答案,但都太老了(大多数是 4-5 岁);我仍然尝试使用很多,但其中 none 有效。

我也试着看了官方文档,但我没有完全理解。

首先你需要在数据库中存储过程

CREATE PROCEDURE RegisterUser @username varchar(30), @password varchar(10)
AS
BEGIN
INSERT INTO userinfo (username, password) 
VALUES (@username, @password)
END;
________________________________________________________________________________________
CREATE PROCEDURE LoginUser @username varchar(30), @password varchar(10)
AS
BEGIN
SELECT username, password 
FROM userinfo 
WHERE EXISTS (
      SELECT username, password 
      FROM userinfo 
      WHERE userinfo.username = @username AND userinfo.password = @password
)
END;

然后你就可以在你的代码中使用它们了:

var username, password;
var userInfoArray = [username, password]
var registrationProcedure = "EXEC RegisterUser @username = , @password = "
var loginProcedure = "EXEC LoginUser @username = , @password = "
    
function userRegistration (userInfoArray) {
         dbConnection.query(registrationProcedure, userInfoArray,
         function(err, results, fields) {
            if (err) throw err
            console.log("registered new user")
        })
}

function userLogin (userInfoArray) {
         dbConnection.query(loginProcedure, userInfoArray,
         function(err, results, fields) {
            if (err) throw err
            console.log(results)
        })
}

请注意,使用存储过程并不意味着您不再像以前那样将参数传递给查询(字符串连接),只是意味着您将查询实现隐藏在数据库中,这提高了安全性。

Here 是我用于此答案的参考。

这只是一个示例,但我也会避免对输入变量使用相同的列名称,并仅将密码的哈希值存储在数据库中。因此,在注册期间保存之前和比较部分之前 WHERE ... AND userinfo.password = @password 我会对来自请求的密码进行哈希处理。