О насБлогКонтакты
Веб-разработка15 мая 2000 г. 6 мин 105Обновлено: 22 июня 2026 г.

Авторизация и сессии в Classic ASP: корпоративный веб 2000 года

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

В 2000 году, если вы разрабатывали корпоративное веб-приложение для серверов на Windows, вы использовали Active Server Pages. Стек Microsoft: Windows NT 4 или Windows 2000 Server, IIS 5, SQL Server 7 или 2000, скриптование на VBScript.

PHP работал на Unix и требовал Apache. Perl требовал знания Unix. ASP работал на Windows, управлялся стандартными инструментами Microsoft, интегрировался с Active Directory и использовал VBScript - язык, который IT-отделы уже знали по макросам Office. Для компаний, вложившихся в инфраструктуру Microsoft, ASP был очевидным выбором.

Система авторизации с управлением сессиями - первая реальная задача веб-приложения. Полная реализация 2000 года.


Объект Session: встроенное управление состоянием

Объект Session в ASP - это серверный словарь на каждого пользователя, идентифицируемый куки (ASPSESSIONID), который IIS устанавливал автоматически. Никакого ручного управления куки - IIS управлял сессионным куки, а код просто читал и писал в Session как в словарь.

<%
' login.asp - Classic ASP, авторизация с SQL Server
' VBScript, IIS 5, SQL Server 2000, 2000 год

Option Explicit

Dim strError
strError = ""

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

    Dim strUsername, strPassword
    strUsername = Trim(Request.Form("username"))
    strPassword = Trim(Request.Form("password"))

    If strUsername = "" Or strPassword = "" Then
        strError = "Логин и пароль обязательны."
    Else
        Dim bAuthenticated
        bAuthenticated = AuthenticateUser(strUsername, strPassword)

        If bAuthenticated Then
            ' Сохраняем идентификатор пользователя в сессии
            Session("IsLoggedIn") = True
            Session("Username")   = strUsername
            Session("LoginTime")  = Now()

            Response.Redirect "dashboard.asp"
            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="#FFFFFF">
<h2>Вход в систему</h2>
<% If strError <> "" Then %>
  <p><font color="red"><b><%= Server.HTMLEncode(strError) %></b></font></p>
<% End If %>
<form method="POST" action="login.asp">
  <table border="0" cellpadding="4">
    <tr>
      <td>Логин:</td>
      <td><input type="text" name="username" size="25"></td>
    </tr>
    <tr>
      <td>Пароль:</td>
      <td><input type="password" name="password" size="25"></td>
    </tr>
    <tr>
      <td></td>
      <td><input type="submit" value="Войти"></td>
    </tr>
  </table>
</form>
</body>
</html>

Аутентификация через ADODB

<%
' Функция аутентификации - часть login.asp или отдельный include-файл

Function AuthenticateUser(strUsername, strPassword)
    AuthenticateUser = False

    Dim oConn, oRS, oCmd

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

    ' DSN-less строка подключения к SQL Server 2000
    oConn.Open "Provider=SQLOLEDB;" & _
               "Data Source=SQLSERVER01;" & _
               "Initial Catalog=MyAppDB;" & _
               "User ID=webapp_user;" & _
               "Password=webapp_pass;"

    ' ВНИМАНИЕ: многие разработчики в 2000 году конкатенировали строки напрямую.
    ' Это - SQL-инъекция. Правильный подход уже тогда: параметризованные запросы.

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

    oCmd.CommandText = "SELECT UserID, PasswordHash, IsActive " & _
                       "FROM Users WHERE Username = ?"
    oCmd.CommandType = 1   ' adCmdText

    ' Параметр - защита от SQL-инъекций
    oCmd.Parameters.Append oCmd.CreateParameter("@username", 200, 1, 50, strUsername)
    ' 200 = adVarChar, 1 = adParamInput, 50 = макс. длина

    Set oRS = oCmd.Execute()

    If Not oRS.EOF Then
        Dim storedHash
        storedHash = oRS("PasswordHash")

        ' Сравнение хеша - MD5 был стандартом в 2000 году
        ' (bcrypt появился в веб-разработке только к 2007-2010 годам)
        If MD5Hash(strPassword) = storedHash Then
            If CBool(oRS("IsActive")) Then
                AuthenticateUser = True
                Call LogLoginAttempt(CStr(oRS("UserID")), True)
            End If
        Else
            Call LogLoginAttempt("0", False)
        End If
    End If

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

End Function
%>

Защита страниц через проверку сессии

Каждая защищённая страница включала в начало файл с проверкой - директива #include в ASP позволяла переиспользовать этот код:

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

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

' Проверка таймаута сессии - 30 минут неактивности
Dim dtLoginTime
dtLoginTime = Session("LoginTime")

If IsDate(dtLoginTime) Then
    If DateDiff("n", dtLoginTime, Now()) > 30 Then
        Session.Abandon
        Response.Redirect "login.asp?msg=timeout"
        Response.End
    End If
End If

Session("LoginTime") = Now()
%>

Защищённая страница:

<%
' dashboard.asp
Option Explicit
%>
<!-- #include file="auth_check.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>
<h1>Добро пожаловать, <%= Server.HTMLEncode(Session("Username")) %>!</h1>
<p>Вы вошли в систему. <a href="logout.asp">Выйти</a></p>
</body>
</html>

Выход:

<%
' logout.asp
Session.Abandon   ' Очищает все переменные сессии, инвалидирует куки
Response.Redirect "login.asp"
Response.End
%>

Схема таблицы SQL Server

-- SQL Server 2000, запускать в Query Analyzer

CREATE TABLE Users (
    UserID       INT IDENTITY(1,1) PRIMARY KEY,
    Username     VARCHAR(50)  NOT NULL UNIQUE,
    PasswordHash VARCHAR(32)  NOT NULL,   -- MD5 в hex, 32 символа
    Email        VARCHAR(100) NOT NULL,
    IsActive     BIT          NOT NULL DEFAULT 1,
    CreatedDate  DATETIME     NOT NULL DEFAULT GETDATE(),
    LastLogin    DATETIME     NULL
)
GO

CREATE UNIQUE INDEX IX_Users_Username ON Users (Username)
GO

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

Вставка пользователя с хешем пароля:

<%
' register.asp
' MD5 в Classic ASP: обычно подключали внешний include-файл md5.asp
' <!-- #include file="md5.asp" -->

Dim strHashedPassword
strHashedPassword = MD5(Request.Form("password"))

Dim oConn, oCmd
Set oConn = Server.CreateObject("ADODB.Connection")
oConn.Open strConnectionString

Set oCmd = Server.CreateObject("ADODB.Command")
Set oCmd.ActiveConnection = oConn
oCmd.CommandText = "INSERT INTO Users (Username, PasswordHash, Email) VALUES (?, ?, ?)"
oCmd.Parameters.Append oCmd.CreateParameter("@u",     200, 1, 50,  strUsername)
oCmd.Parameters.Append oCmd.CreateParameter("@ph",    200, 1, 32,  strHashedPassword)
oCmd.Parameters.Append oCmd.CreateParameter("@email", 200, 1, 100, strEmail)
oCmd.Execute

oConn.Close
Set oCmd  = Nothing
Set oConn = Nothing
%>

Объект Application и Global.asa

Пока Session был уникальным для каждого пользователя, Application был общим для всех:

<%
' Используется в Global.asa, Application_OnStart
Application.Lock
Application("ConnectionString") = "Provider=SQLOLEDB;Data Source=..."
Application("SiteVersion")      = "2.1.4"
Application("StartTime")        = Now()
Application.Unlock
%>

Global.asa - файл событий приложения, аналог bootstrap в современных фреймворках:

' Global.asa - размещается в корне веб-приложения

<SCRIPT LANGUAGE="VBScript" RUNAT="Server">
Sub Application_OnStart
    Application("TotalVisits") = 0
End Sub

Sub Session_OnStart
    Application.Lock
    Application("TotalVisits") = Application("TotalVisits") + 1
    Application.Unlock

    Session.Timeout = 30   ' минуты
End Sub

Sub Session_OnEnd
    ' Очистить ресурсы сессии
End Sub
</SCRIPT>

Переход на ASP.NET

В 2000-2001 году Microsoft разрабатывал ASP.NET, вышедший в январе 2002 года. Архитектурный сдвиг был значительным: от интерпретируемого VBScript к компилируемому C# или VB.NET, от ручного управления сессиями и формами к модели Web Forms с серверными контролами, от ADODB.Recordset к ADO.NET dataset.

Classic ASP разработчики, понимавшие модель объектов Session/Application/Request/Response, переходили на ASP.NET органично - те же абстракции, реализованные лучше. Classic ASP оставался в продакшене долгие годы после выхода ASP.NET; многие приложения работали на нём вплоть до эры Windows Server 2008, когда хостеры начали его депрекировать.

Паттерны - сессионная аутентификация, параметризованные запросы к БД, серверный рендеринг с include-файлами - это паттерны современной веб-разработки. Технология сменилась; архитектура осталась прежней.

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

Google Chrome и V8: когда JavaScript стал быстрым (2008)aunimeda
Веб-разработка

Google Chrome и V8: когда JavaScript стал быстрым (2008)

2 сентября 2008 года Google выпустил Chrome. Не браузер - манифест. Внутри был V8: JIT-компилятор JavaScript, написанный с нуля. SunSpider показал, что V8 в 10 раз быстрее Firefox 3. За один день ожидания от JavaScript радикально изменились. Начался browser war 2.0.

Ajax: имя, изменившее веб (2005)aunimeda
Веб-разработка

Ajax: имя, изменившее веб (2005)

18 февраля 2005 года Джесси Джеймс Гаррет опубликовал статью «Ajax: новый подход к веб-приложениям». Технология не была новой - XMLHttpRequest существовал с 1999 года. Но имя изменило всё: разработчики получили паттерн, словарь и разрешение думать о браузере как о платформе приложений.

WordPress 0.7: день, когда блоггинг стал доступен всем (2003)aunimeda
Веб-разработка

WordPress 0.7: день, когда блоггинг стал доступен всем (2003)

27 мая 2003 года Мэтт Мулленвег выпустил WordPress 0.7 - 2500 строк PHP. Никаких плагинов, никаких тем, один шаблон. Пять минут на установку. Movable Type требовал часа настройки Perl. Это маленькое различие изменило весь веб.

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

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

Разработка сайтов

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