О насБлогКонтакты
Технологии14 июля 2000 г. 7 мин 99Обновлено: 18 мая 2026 г.

Classic ASP и первые корпоративные веб-системы Бишкека (2000)

AunimedaAunimeda
📋 Содержание

Classic ASP и первые корпоративные веб-системы Бишкека (2000)

2000 год. Бишкек. Количество интернет-пользователей в Кыргызстане перешагнуло отметку в 50 тысяч. Крупные компании - банки, импортёры техники, телекоммуникационные операторы - начали воспринимать сайт не просто как визитку, а как инструмент работы с партнёрами и клиентами.

Первые задачи: закрытые разделы для оптовых покупателей, личные кабинеты, скачивание актуального прайс-листа только после авторизации. Всё это требовало сессионной авторизации. Разработчики, работавшие на Windows-инфраструктуре (а большинство бишкекских корпоративных машин работало именно на Windows), выбирали Microsoft ASP.


Полная система авторизации для бишкекского сайта

<%
' login.asp - система входа, Бишкек 2000 год
' IIS 5, VBScript, SQL Server 7/2000
' Кодировка: windows-1251

Option Explicit

Dim strError
strError = ""

If Request.ServerVariables("REQUEST_METHOD") = "POST" Then

    Dim strLogin, strPass
    strLogin = Trim(Request.Form("login"))
    strPass  = Trim(Request.Form("password"))

    If strLogin = "" Or strPass = "" Then
        strError = "Заполните оба поля."
    Else
        Dim bOk
        bOk = VerifyUser(strLogin, strPass)

        If bOk Then
            Session("LoggedIn")  = True
            Session("Login")     = strLogin
            Session("LoginTime") = Now()

            Dim strNext
            strNext = Request.QueryString("next")
            If strNext = "" Then strNext = "dashboard.asp"
            Response.Redirect strNext
            Response.End
        Else
            strError = "Неверный логин или пароль."
        End If
    End If
End If
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <title>Вход - Личный кабинет</title>
  <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
</head>
<body bgcolor="#EFEFEF">
<br><br>
<table width="320" border="0" cellpadding="0" cellspacing="0" align="center">
  <tr>
    <td bgcolor="#003399" height="26">
      <font face="Arial" size="2" color="#FFFFFF">
        &nbsp;<b>Вход в закрытый раздел</b>
      </font>
    </td>
  </tr>
  <tr>
    <td bgcolor="#FFFFFF"
        style="border:1px solid #003399; border-top:0; padding:14px;">
      <% If strError <> "" Then %>
        <p style="margin:0 0 10px 0;">
          <font face="Arial" size="2" color="#CC0000">
            <b><%= Server.HTMLEncode(strError) %></b>
          </font>
        </p>
      <% End If %>
      <form method="POST" action="login.asp">
        <table border="0" cellpadding="3">
          <tr>
            <td><font face="Arial" size="2">Логин:</font></td>
            <td>
              <input type="text" name="login" size="22"
                     style="border:1px solid #999; font-size:12px;">
            </td>
          </tr>
          <tr>
            <td><font face="Arial" size="2">Пароль:</font></td>
            <td>
              <input type="password" name="password" size="22"
                     style="border:1px solid #999; font-size:12px;">
            </td>
          </tr>
          <tr>
            <td colspan="2" align="right">
              <input type="submit" value="Войти"
                     style="background:#003399; color:#FFF;
                            border:1px solid #001166;
                            padding:3px 14px; cursor:pointer;
                            font-size:12px; font-weight:bold;">
            </td>
          </tr>
        </table>
      </form>
    </td>
  </tr>
  <tr>
    <td>
      <font face="Arial" size="1" color="#666666">
        &nbsp;Нет доступа?
        <a href="mailto:admin@mojacompany.kg">Обратитесь к администратору</a>
      </font>
    </td>
  </tr>
</table>
</body>
</html>

Функция проверки пароля через ADODB

<%
' Функция VerifyUser - проверка логина/пароля по базе данных
' Включается в login.asp через <!-- #include file="functions.asp" -->

Function VerifyUser(strLogin, strPass)
    VerifyUser = False

    Dim oConn, oCmd, oRS

    Set oConn = Server.CreateObject("ADODB.Connection")

    ' Строка подключения к SQL Server
    ' В Бишкеке 2000 года сервер обычно стоял в том же офисе
    oConn.Open "Provider=SQLOLEDB;" & _
               "Data Source=BISHKEK-SRV01;" & _
               "Initial Catalog=CompanyDB;" & _
               "User ID=web_user;" & _
               "Password=web_pass123;"

    ' Параметризованный запрос - защита от SQL-инъекций
    ' (даже в 2000 году это был правильный подход, хотя многие им пренебрегали)
    Set oCmd = Server.CreateObject("ADODB.Command")
    Set oCmd.ActiveConnection = oConn

    oCmd.CommandText = "SELECT UserID, PasswordMD5, FullName, " & _
                       "       CompanyName, IsActive " & _
                       "FROM   Users " & _
                       "WHERE  Login = ?"
    oCmd.CommandType = 1   ' adCmdText

    oCmd.Parameters.Append _
        oCmd.CreateParameter("@login", 200, 1, 50, strLogin)
    ' adVarChar=200, adParamInput=1

    Set oRS = oCmd.Execute()

    If Not oRS.EOF Then
        Dim bActive
        bActive = CBool(oRS("IsActive"))

        If bActive Then
            ' MD5-хеш - стандарт хранения паролей в 2000 году
            ' md5.asp подключался отдельно как include-файл
            ' (скачивался с aspfaq.com или codeguru.com)
            Dim sHash
            sHash = LCase(MD5(strPass))

            If sHash = LCase(CStr(oRS("PasswordMD5"))) Then
                VerifyUser = True

                ' Сохраняем данные пользователя в сессии
                Session("UserID")      = CStr(oRS("UserID"))
                Session("FullName")    = CStr(oRS("FullName"))
                Session("CompanyName") = CStr(oRS("CompanyName"))

                ' Обновить время последнего входа и IP
                Dim strIP
                strIP = Request.ServerVariables("REMOTE_ADDR")
                Call LogAccess(CStr(oRS("UserID")), strIP, True, oConn)
            Else
                ' Неверный пароль - логируем попытку
                Call LogAccess(CStr(oRS("UserID")), _
                     Request.ServerVariables("REMOTE_ADDR"), False, oConn)
            End If
        End If
    End If

    oRS.Close
    oConn.Close
    Set oRS   = Nothing
    Set oCmd  = Nothing
    Set oConn = Nothing
End Function

Sub LogAccess(strUID, strIP, bSuccess, oConn)
    Dim oCmd
    Set oCmd = Server.CreateObject("ADODB.Command")
    Set oCmd.ActiveConnection = oConn
    oCmd.CommandText = "INSERT INTO AccessLog " & _
                       "(UserID, IPAddress, LoginTime, Success) " & _
                       "VALUES (?, ?, GETDATE(), ?)"
    oCmd.Parameters.Append oCmd.CreateParameter("@uid",     3, 1, 4,  CLng(strUID))
    oCmd.Parameters.Append oCmd.CreateParameter("@ip",    200, 1, 15, strIP)
    oCmd.Parameters.Append oCmd.CreateParameter("@ok",     11, 1, 1,  bSuccess)
    oCmd.Execute
    Set oCmd = Nothing
End Sub
%>

auth_check.asp и защита страниц

<%
' auth_check.asp - вставлять в начало каждой защищённой страницы
' <!-- #include file="auth_check.asp" -->

If Not CBool(Session("LoggedIn")) Then
    Response.Redirect "login.asp?next=" & _
        Server.URLEncode(Request.ServerVariables("URL"))
    Response.End
End If

' Таймаут сессии: 60 минут (корпоративный стандарт)
If IsDate(Session("LoginTime")) Then
    If DateDiff("n", Session("LoginTime"), Now()) > 60 Then
        Session.Abandon
        Response.Redirect "login.asp?msg=timeout"
        Response.End
    End If
End If
Session("LoginTime") = Now()
%>

Пример защищённой страницы - прайс-лист для партнёров:

<%
Option Explicit
%>
<!-- #include file="auth_check.asp" -->
<!-- #include file="header.asp" -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <title>Прайс-лист партнёра</title>
  <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
</head>
<body>
<h2>Добро пожаловать, <%= Server.HTMLEncode(Session("FullName")) %>!</h2>
<p>Компания: <b><%= Server.HTMLEncode(Session("CompanyName")) %></b>
   | <a href="logout.asp">Выйти</a></p>
<hr>
<%
Dim oConn, oRS, oCmd
Set oConn = Server.CreateObject("ADODB.Connection")
oConn.Open Application("DB_CONN")

Set oCmd = Server.CreateObject("ADODB.Command")
Set oCmd.ActiveConnection = oConn

' Прайс-лист актуален на дату запроса
oCmd.CommandText = "SELECT p.SKU, p.NameRU, p.PriceKGS, p.Stock " & _
                   "FROM Products p " & _
                   "WHERE p.IsActive = 1 AND p.StockQty > 0 " & _
                   "ORDER BY p.CategoryID, p.NameRU"
oCmd.CommandType = 1

Set oRS = oCmd.Execute()
%>
<h3>Актуальный прайс-лист
  (<%= FormatDateTime(Now(), 2) %>)</h3>
<table border="1" cellpadding="5" cellspacing="0"
       style="border-collapse:collapse; font-size:12px;">
  <tr bgcolor="#003399">
    <th><font color="#FFF">Артикул</font></th>
    <th><font color="#FFF">Наименование</font></th>
    <th><font color="#FFF">Цена (сом)</font></th>
    <th><font color="#FFF">Наличие</font></th>
  </tr>
  <% Dim rowBg : rowBg = "#FFFFFF" %>
  <% Do While Not oRS.EOF %>
    <tr bgcolor="<%= rowBg %>">
      <td><%= Server.HTMLEncode(oRS("SKU")) %></td>
      <td><%= Server.HTMLEncode(oRS("NameRU")) %></td>
      <td align="right">
        <%= FormatNumber(oRS("PriceKGS"), 2) %>
      </td>
      <td align="center">
        <% If CInt(oRS("Stock")) > 10 Then %>
          <font color="green">&#10003; В наличии</font>
        <% ElseIf CInt(oRS("Stock")) > 0 Then %>
          <font color="orange">Мало (%= oRS("Stock") %)</font>
        <% Else %>
          <font color="red">Нет</font>
        <% End If %>
      </td>
    </tr>
    <% rowBg = IIf(rowBg = "#FFFFFF", "#F5F5F5", "#FFFFFF") %>
    <% oRS.MoveNext %>
  <% Loop %>
</table>
<%
oRS.Close : oConn.Close
Set oRS = Nothing : Set oConn = Nothing
%>
</body>
</html>

Схема БД для кыргызстанского торгового сайта

-- SQL Server 7/2000, Query Analyzer, Бишкек 2000 год

CREATE TABLE Users (
    UserID      INT IDENTITY(1,1) PRIMARY KEY,
    Login       VARCHAR(50)   NOT NULL UNIQUE,
    PasswordMD5 VARCHAR(32)   NOT NULL,
    FullName    NVARCHAR(100) NOT NULL,
    CompanyName NVARCHAR(150) NULL,
    Phone       VARCHAR(30)   NULL,
    IsActive    BIT           NOT NULL DEFAULT 1,
    CreatedAt   DATETIME      NOT NULL DEFAULT GETDATE(),
    LastLogin   DATETIME      NULL
)
GO

CREATE TABLE Products (
    ProductID  INT IDENTITY(1,1) PRIMARY KEY,
    SKU        VARCHAR(20)    NOT NULL UNIQUE,
    NameRU     NVARCHAR(200)  NOT NULL,
    CategoryID INT            NOT NULL,
    PriceKGS   DECIMAL(10,2)  NOT NULL,  -- в кыргызских сомах
    Stock      INT            NOT NULL DEFAULT 0,
    IsActive   BIT            NOT NULL DEFAULT 1
)
GO

CREATE TABLE AccessLog (
    LogID      INT IDENTITY(1,1) PRIMARY KEY,
    UserID     INT          NOT NULL,
    IPAddress  VARCHAR(15)  NOT NULL,
    LoginTime  DATETIME     NOT NULL DEFAULT GETDATE(),
    Success    BIT          NOT NULL
)
GO

Особенности ASP-разработки в Бишкеке 2000 года

Сервер в офисе. В отличие от казахстанских компаний, которые чаще арендовали хостинг в Москве, бишкекские корпоративные клиенты нередко держали сервер физически в офисе - поставили старый Pentium II, накатили Windows 2000 Server, IIS 5, SQL Server 7. Это означало: полный контроль, но никакой резервации - свет выключили, сервер лежит.

NVARCHAR для кыргызского. Кыргызские буквы Ң, Ү, Ө не входили в windows-1251. SQL Server 2000 поддерживал Unicode через NVARCHAR - это был правильный путь:

' Параметр с Unicode-строкой:
oCmd.Parameters.Append _
    oCmd.CreateParameter("@name", 202, 1, 100, strFullName)
' 202 = adVarWChar (Unicode) вместо 200 (adVarChar cp1251)
' Так кыргызские имена хранились корректно уже в 2000 году

Переход к PHP к 2003 году. Бишкекские компании, начавшие с ASP в 2000-2001 годах, к 2003-2004 году переходили на PHP. Причина та же: PHP-хостинг был дешевле Windows VPS, документации на русском больше, сообщество активнее. Навыки ASP при этом не пропадали - Request/Response/Session-модель один в один отображалась на PHP $_POST/$_GET/$_SESSION.

Читайте также

Первые сайты на PHP3 в 2002: как мы верстали до CSS, без фреймворков и без Stack Overflowaunimeda
Технологии

Первые сайты на PHP3 в 2002: как мы верстали до CSS, без фреймворков и без Stack Overflow

В 2002 году не было CSS Zen Garden, не было jQuery, не было документации на русском. Был PHP 3/4, были таблицы для вёрстки, был Dreamweaver с WYSIWYG, и было сообщество на форуме phpclub.ru. Вот как выглядела реальная веб-разработка 20 лет назад.

DHTML-навигация в Бишкеке 2001 года: выпадающие меню на чистом JavaScriptaunimeda
Технологии

DHTML-навигация в Бишкеке 2001 года: выпадающие меню на чистом JavaScript

В 2001 году выпадающее меню без Flash и без перезагрузки страницы - это было то, что отличало профессиональный бишкекский сайт от любительского. DHTML на JavaScript + CSS. Работало в IE5 и Netscape 6. Вот как мы это делали, что ломалось и почему 300 мс до сих пор актуально.

Java-апплеты: интерактивный веб в Бишкеке 1999 годаaunimeda
Технологии

Java-апплеты: интерактивный веб в Бишкеке 1999 года

В 1999 году Java-апплеты обещали революцию: настоящие приложения прямо в браузере. На dial-up 33 кбит/с с задержкой 200-400 мс до европейских серверов - загрузка JVM занимала 30-60 секунд. Бишкекские разработчики всё равно их писали. Код, опыт, провал.

Нужна IT-разработка для вашего бизнеса?

Разрабатываем сайты, мобильные приложения и AI-решения для бизнеса в Кыргызстане. Бесплатная консультация.

Получить консультацию Все статьи