Как присвоить значения Профиля?

Используйте подготовленные операторы и параметризованные запросы. Это операторы SQL, которые отправляются и анализируются сервером базы данных отдельно от любых параметров. Таким образом, злоумышленник не может внедрить вредоносный SQL.

У вас в основном есть два варианта:

  1. Использование PDO (для любой поддерживаемый драйвер базы данных):
    $stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
    
    $stmt->execute(array('name' => $name));
    
    foreach ($stmt as $row) {
        // do something with $row
    }
    
  2. Использование MySQLi (для MySQL):
    $stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
    $stmt->bind_param('s', $name); // 's' specifies the variable type => 'string'
    
    $stmt->execute();
    
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) {
        // do something with $row
    }
    

Если вы подключаетесь к база данных, отличная от MySQL, есть вторая опция, зависящая от драйвера, к которой вы можете обратиться (например, pg_prepare() и pg_execute() для PostgreSQL). PDO является универсальной опцией.

Правильная настройка соединения

Обратите внимание, что при использовании PDO для доступа к базе данных MySQL real подготовленные операторы не используются по умолчанию. Чтобы исправить это, вы должны отключить эмуляцию подготовленных операторов. Пример создания соединения с использованием PDO:

$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');

$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

В приведенном выше примере режим ошибки не является строго необходимым, но рекомендуется добавить его. Таким образом, сценарий не остановится с Fatal Error, когда что-то пойдет не так. И это дает разработчику шанс catch получить любую ошибку (ы), которые являются throw n как PDOException s.

Однако обязательной является первая setAttribute() строка, которая сообщает PDO об отключении эмулируемых подготовленных операторов и использует подготовленные операторы real . Это гарантирует, что оператор и значения не будут разбираться с PHP перед отправкой на сервер MySQL (предоставление возможности злоумышленнику возможности внедрить вредоносный SQL).

Хотя вы можете установить charset в варианты конструктора, важно отметить, что «более старые» версии PHP (& lt; 5.3.6) молча игнорировали параметр charset в DSN.

Объяснение

Случается, что оператор SQL, который вы передаете prepare, анализируется и компилируется сервером базы данных. Указав параметры (либо ?, либо именованный параметр, такой как :name в примере выше), вы указываете механизм базы данных, в который вы хотите включить фильтр. Затем, когда вы вызываете execute, подготовленный оператор объединяется со значениями параметров, которые вы указываете.

Важно то, что значения параметров объединены с компилируемым оператором, а не с строкой SQL. SQL-инъекция работает, обманывая сценарий, включая вредоносные строки, когда он создает SQL для отправки в базу данных. Поэтому, отправляя фактический SQL отдельно от параметров, вы ограничиваете риск того, что закончите то, чего не намеревались. Любые параметры, которые вы отправляете при использовании подготовленного оператора, будут обрабатываться только как строки (хотя механизм базы данных может сделать некоторую оптимизацию, поэтому, конечно, параметры могут также оказаться как числа). В приведенном выше примере, если переменная $name содержит 'Sarah'; DELETE FROM employees, результатом будет просто поиск строки "'Sarah'; DELETE FROM employees", и вы не получите пустую таблицу .

Еще одно преимущество использования подготовленных операторов состоит в том, что если вы выполняете один и тот же оператор много раз в одном сеансе, он будет анализироваться и компилироваться один раз, давая вам некоторую прибыль от скорости.

О, и поскольку вы спросили, как это сделать для вставки, вот пример (с использованием PDO):

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));

Могут ли подготовленные операторы использоваться для динамических запросов?

Пока вы все еще можете использовать подготовленные операторы для параметров запроса, сама структура самого динамического запроса не может быть параметризована, и некоторые функции запроса не могут быть параметризованы.

Для этих конкретных сценариев лучше всего использовать фильтр белого списка, который ограничивает возможные значения.

// Value whitelist
// $dir can only be 'DESC' otherwise it will be 'ASC'
if (empty($dir) || $dir !== 'DESC') {
   $dir = 'ASC';
}

110
задан pupeno 22 May 2010 в 12:50
поделиться

6 ответов

Сегодня у меня была такая же проблема, и я многому научился.

В Visual Studio есть два типа проектов - «Проекты веб-сайтов» и «Проекты веб-приложений». По причинам, которые для меня являются полной загадкой, проекты веб-приложений не могут использовать профиль . напрямую ... строго типизированный класс не создается для вас волшебным образом из файла Web.config, поэтому вам придется использовать собственный.

Пример кода в MSDN предполагает, что вы используете проект веб-сайта, и они сообщают вам просто нужно добавить раздел в свой Web.config и использовать свойство Profile. , но это не работает в Проекты веб-приложений.

У вас есть два варианта развертывания собственных:

(1) Используйте Конструктор веб-профилей . Это настраиваемый инструмент, который вы добавляете в Visual Studio, который автоматически генерирует нужный объект профиля из вашего определения в Web.config.

Я решил не делать этого, потому что не хотел, чтобы мой код зависел от этого дополнительного инструмента. для компиляции, что могло вызвать проблемы у кого-то в будущем, когда они попытались построить мой код, не осознавая, что им нужен этот инструмент.

(2) Создайте свой собственный класс, производный от ProfileBase для представляют ваш индивидуальный профиль. Это проще, чем кажется. Вот очень простой пример, который добавляет строковое поле профиля «FullName»:

В вашем web.config:

<profile defaultProvider="SqlProvider" inherits="YourNamespace.AccountProfile">

<providers>
     <clear />
     <add name="SqlProvider"
          type="System.Web.Profile.SqlProfileProvider"
          connectionStringName="sqlServerMembership" />
</providers>

</profile>

В файле с именем AccountProfile.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Profile;
using System.Web.Security;

namespace YourNamespace
{
    public class AccountProfile : ProfileBase
    {
        static public AccountProfile CurrentUser
        {
            get { return (AccountProfile)
                         (ProfileBase.Create(Membership.GetUser().UserName)); }
        }

        public string FullName
        {
            get { return ((string)(base["FullName"])); }
            set { base["FullName"] = value; Save(); }
        }

        // add additional properties here
    }
}

Чтобы установить значение профиля:

AccountProfile.CurrentUser.FullName = "Snoopy";

Чтобы получить значение профиля

string x = AccountProfile.CurrentUser.FullName;
178
ответ дан 24 November 2019 в 03:13
поделиться

То, когда Вы создаете новый проект веб-сайта в Visual Studio тогда объект, который возвращается из Профиля, будет (автоматически) сгенерировано для Вас. При создании проекта веб-приложения или проекта MVC Вы будете иметь к самокрутке.

Это, вероятно, звучит более трудным, чем это. Необходимо сделать следующее:

  • Создают базу данных с помощью aspnet_regsql.exe , Этот инструмент установлен наряду с платформой.NET.
  • Запись класс, который происходит из ProfileGroupBase или устанавливает Разработчика профиля в сетях (WPB), который может генерировать класс для Вас из определения в сети. Конфигурация. Я использовал WPB некоторое время, и вплоть до сих пор он сделал то, что ожидается его. Если у Вас есть много свойств, использование WPB может сэкономить довольно мало времени.
  • Удостоверяются, что соединение с базой данных правильно настроено в сети. Конфигурация.
  • Теперь Вы установлены создать экземпляр своего класса профиля (в контроллере)
  • , Вам, вероятно, будут нужны значения свойств профиля в Ваших представлениях. Мне нравится передавать сам объект профиля представлению (не отдельные свойства).
8
ответ дан Captain Sensible 24 November 2019 в 03:13
поделиться

При использовании проекта веб-приложения Вы не можете получить доступ к объекту Профиля во время проектирования out-of-the-box. Вот утилита, которая, предположительно, делает это для Вас: http://weblogs.asp.net/joewrobel/archive/2008/02/03/web-profile-builder-for-web-application-projects.aspx . Лично, та утилита вызвала ошибку в моем проекте, таким образом, я закончил тем, что прокрутил свой собственный класс профиля для наследования ProfileBase. Не было трудно сделать вообще.

3
ответ дан nshaw 24 November 2019 в 03:13
поделиться

Конструктор веб-профилей отлично поработал у меня. Сгенерированный им класс содержит гораздо больше, чем описано в сообщении Джоэла. Я не знаю, действительно ли он нужен или полезен.

В любом случае, для тех, кто ищет простой способ создания класса, но не хочет иметь зависимость от внешнего инструмента сборки, вы всегда можете

  • использовать конструктор веб-профилей
  • удалите все его следы!
  • продолжайте использовать сгенерированный класс профиля

ИЛИ (непроверенный, но может работать)

  • создайте веб сайт проект
  • создайте свой элемент
  • прикрепите сгенерированный класс и скопируйте его в свой веб проект проект

, если этот второй подход работает, может ли кто-нибудь сообщить мне для справок в будущем

1
ответ дан 24 November 2019 в 03:13
поделиться

Пошаговое руководство MSDN для создания настраиваемого класса (также известного как метод Джоэла):
http://msdn.microsoft.com/en-us/magazine/cc163624.aspx

2
ответ дан 24 November 2019 в 03:13
поделиться

Отличный пост,

Только замечание по web.config если вы не укажете атрибут inherit в элементе профиля. вам нужно будет указать каждое отдельное свойство профиля внутри элемента профиля в web.config, как показано ниже

 <properties>
    <clear/>
    <add name="property-name-1" />
    <add name="property-name-2" />
    ..........

 </properties>
0
ответ дан 24 November 2019 в 03:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: