4

有这样一个模块代码(用于处理数据库):

use tokio_postgres::{NoTls, Error};

pub async fn hello() -> Result<(), Error> {

    // Connect to the database.
    let (client, connection) =
        tokio_postgres::connect("host=localhost user=postgres", NoTls).await?;

    // The connection object performs the actual communication with the database,
    // so spawn it off to run on its own.
    tokio::spawn(async move {
        if let Err(e) = connection.await {
            eprintln!("connection error: {}", e);
        }
    });

    // Now we can execute a simple statement that just returns its parameter.
    let rows = client
        .query("SELECT $1::TEXT", &[&"hello world"])
        .await?;

    // And then check that we got back the same string we sent over.
    let value: &str = rows[0].get(0);
    assert_eq!(value, "hello world");

    Ok(())
}

问题:
在这种情况下,应该如何编写对数据库的访问?
(该指南没有说任何关于它的内容 - 或者我没有完全理解它。)
https://docs.rs/tokio-postgres/0.5.5/tokio_postgres/
在这种情况下什么机制可以保护对数据库的访问从 sql 注入?
需要最简单的通用用例。

4

1 回答 1

4

client.query(statement, params) will convert the first argument statement to a prepared statement and execute it with the params.

To be safe from sql injection, make sure that all user data is passed in the second params argument.

DO NOT DO THIS:

let id = "SOME DATA FROM THE USER";

let rows = client
  .query(format!("SELECT * FROM SomeTable WHERE id = {}", id), &[])
  .await?;

DO THIS:

let id = "SOME DATA FROM THE USER";

let rows = client
  .query("SELECT * FROM SomeTable WHERE id = $1", &[&id])
  .await?;

Explanation:

In tokio-postgres most client methods (query* or execute*) can accept either a &str or Statement for the sql statement. If passed a &str it will create a prepared statement (Statement object) for you.

于 2020-09-14T08:51:15.873 回答