Как запретить нескольким окнам браузера использовать один и тот же сеанс в asp.net - PullRequest
15 голосов
/ 25 марта 2010

У меня есть приложение ASP.net, которое в основном представляет собой экран ввода данных для процесса физического осмотра. Пользователи хотят иметь возможность открывать несколько окон браузера и вводить данные из нескольких проверок одновременно. Сначала я использовал сеансы, основанные на cookie, и, очевидно, это лопнуло.

Я переключился на использование сеансов без файлов cookie, в которых сеанс хранится в URL-адресе, и при тестировании это, похоже, решило проблему. У каждого окна / вкладки браузера был свой идентификатор сеанса, и данные, введенные в одном, не засоряли данные, введенные в другом.

Однако мои пользователи более эффективно ломают вещи, чем я ожидал, и кажется, что им иногда удается получить один и тот же сеанс между браузерами. Я думаю, что они копируют / вставляют адрес с одной вкладки на другую, чтобы открыть приложение, но я пока не смог проверить это (они находятся в другом месте, поэтому я не могу их легко спросить ).

Как не сказать им, что не копируйте и не вставляйте, и не убеждайте их вводить только по одному, как я могу предотвратить возникновение этой ситуации?

Ответы [ 7 ]

5 голосов
/ 25 марта 2010

Подумайте об использовании ViewState вместо Session, поскольку ViewState отображает информацию о состоянии для клиента (HTML-страница). Я не уверен, сможете ли вы когда-нибудь получить подробный контроль над поведением сеанса браузера, потому что идентификатор сеанса поддерживается браузером так, как это делал производитель. Так что ViewState более предсказуем, не только, но и для будущих версий браузера.

3 голосов
/ 30 марта 2011

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

Веб-приложение (и страницы) должны иметь возможность обрабатывать несколько процессов проверки в течение одного сеанса пользователя.

Какие бы данные ни содержались в переменных Session, их нельзя явно показывать для обработки в единственном числе. Они должны храниться в коллекциях , которые легко идентифицируют, какой набор данных принадлежит какому процессу проверки. Каждая отправка страницы обратно на веб-сервер должна содержать идентификатор, к которому относится процесс проверки, так что правильный набор сеансов может быть сопоставлен и извлечен для использования.

концепция псевдокода

var inspectionID = this.inspectionLabel.Text;
var inspectionSets = (Hashtable)Session["inspections"];
var inspection = (Inspection)inspectionSets[inspectionID];
3 голосов
/ 14 марта 2011

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

Храните свою главную веб-страницу в iframe. Имейте javascript, чтобы проверить, находится ли ваша веб-страница в родительском iframe. Если нет, то они открыли несколько окон браузера.

Вы должны убедиться, что все приложение совместимо с iframe.

2 голосов
/ 06 сентября 2013

Решение этой проблемы может быть реализовано следующим образом:

public static class CommonHelper
{
   public static bool SiteGuard
    {
        get
        {
            if(HttpContext.Current.Session["SiteGuard"] == null)
               return true;
            return (bool)HttpContext.Current.Session["SiteGuard"];
        }
        set
        {
            HttpContext.Current.Session["SiteGuard"] = value;
        }
    }
}

public partial class TestPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if(!Page.IsPostBack)
        {
            bool go = false;
            for(int i = 0; i < 50; i++) // wait for the service to work (5 secs max)
            {
                if(CommonHelper.SiteGuard)
                {
                   go = true;
                   break;
                }
                Thread.Sleep(100);
            }
            if(!go)
               Response.Redirect("Login.aspx");

            SiteGuard = false; // from now on, nobody can visit your site
        }
        // Now as long as Page.IsPostBack is true you are in a good shape
    }
}

Добавьте веб-сервис asmx (или любой другой тип сервисов, который вы считаете подходящим) в корневой проект и добавьте в него следующий метод:

    [WebMethod(EnableSession = true)]
    public void FreeSiteGuard()
    {
        HttpContext.Current.Session["SiteGuard"] = null;
    }

На главной странице или на каждой странице добавьте следующий javascript:

<script type="text/javascript">
    window.onbeforeunload = function (e) {
        e = e || window.event;
        if (e) {
            // Invoke web service 
           YourProject.YourWebServiceName.FreeSiteGuard();
        }
    };
</script>

Обратите внимание, что скорость ответа вашего сайта зависит от скорости веб-службы.

2 голосов
/ 03 декабря 2012

Это то, что я использую в ASP.NET MVC, чтобы запретить аутентифицированным пользователям открывать несколько вкладок:

<script language="javascript" type="text/javascript">
    @if(Request.IsAuthenticated)
    {
        <text>
        if (window.name != 'singleWindow') {
            window.location.href = "Content/ErrorPages/SingleTab.htm";
        } 
        </text>
    }
    else
    {
        <text>
        window.name = "singleWindow";
        </text>
    }
</script>

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

Две проблемы:

  • не работает, если JavaScript отключен
  • если по ошибке пользователь закрывает исходную вкладку, а затем вставляет какую-то другую ссылку на мой сайт в адресную строку, пользователь всегда получит страницу с ошибкой. Чтобы дать пользователю возможность восстановиться, я включил ссылку «Выйти» на странице SingleTab.htm, чтобы пользователь мог уничтожить свой файл cookie сеанса и начать новый сеанс.
2 голосов
/ 25 марта 2010

Должны ли пользователи входить в систему с разными учетными записями для доступа к различным физическим осмотрам?Мне кажется, что если PhysicalInspectionID является частью URL, то не должно быть проблем при редактировании нескольких физических проверок одновременно.*http://inspections.mydomain.com/edit/23

Конечно, если они скопируют URL, они получат дубликат другого окна, но это научит их не делать этого.Вместо этого они открывают другое окно и переходят к надлежащему контролю (или добавляют новое) через пользовательский интерфейс.

0 голосов
/ 26 марта 2010

Создать новый sessionId, когда в запросе нет реферера. Это решает проблему копирования и вставки URL. Сохраните идентификатор сессии в URL, как вы сделали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...