[ASP. NET (C \ #)] - 사용자 중복 로그 인 방지 와 session 시간 초과 해결

원본:http://hi.baidu.com/bj1686/blog/item/614b21c6d62813109c163d1c.html
 
1. 웹. config 관련 옵션 을 설정 하려 면 창 인증 과 기본 로그 인 페이지 를 사용 하 십시오. 다음 과 같 습 니 다.

    
    
    
    
< authentication mode ="Forms" >
< forms loginUrl ="default.aspx" ></ forms >
</ authentication >

 
사 이 트 를 설정 하면 익명 으로 방문 할 수 있 습 니 다. 다음 과 같 습 니 다.

    
    
    
    
< authorization >
< allow users ="*" />
</ authorization >

 
그리고 디 렉 터 리 에 있 는 admin 디 렉 터 리 와 익명 로그 인 을 거부 하도록 설정 합 니 다. 다음 과 같 습 니 다.이 소절 은 System. Web 소절 아래 에 있 습 니 다.

    
    
    
    
< location path ="admin" >
< system.web >
< authorization >
< deny users ="?" ></ deny >
</ authorization >
</ system.web >
</ location >

 
http 요청 과 보 낸 인 코딩 을 GB 2312 로 설정 합 니 다. 그렇지 않 으 면 검색 문자열 을 가 져 올 때 문제 가 있 습 니 다. 다음 과 같 습 니 다.

    
    
    
    
< globalization requestEncoding ="gb2312" responseEncoding ="gb2312" />

 
session 시간 초과 시간 을 1 분 으로 설정 하고 cookieless 를 사용 합 니 다. 다음 과 같 습 니 다.

    
    
    
    
< sessionState mode ="InProc" cookieless ="true" timeout ="1" />

 
페이지 추적 을 사용 하기 위해 서 는 디 버 깅 이 편리 하도록 각 페이지 의 trace 를 사용 합 니 다. 다음 과 같 습 니 다.

    
    
    
    
< trace enabled ="true" requestLimit ="1000" pageOutput ="true" traceMode ="SortByTime" localOnly ="true" />

 
 
 
 
 
2. Global. sax 파일 설정
처리 어 플 리 케 이 션Start 방법, 해시 표를 예화 한 다음 Cache 에 저장 합 니 다.

    
    
    
    
protected void Application_Start(Object sender, EventArgs e)
{
Hashtable h
= new Hashtable();
Context.Cache.Insert(
" online " ,h);
}

 
 
Session 에서End 방법 에서 LogoutCache () 방법 을 호출 합 니 다. 방법 원본 은 다음 과 같 습 니 다.

    
    
    
    
/// <summary>
/// Cache , Global.asax Session_End
/// </summary>
public void LogoutCache()
{
Hashtable h
= (Hashtable)Context.Cache[ " online " ];
if (h != null )
{
if (h[Session.SessionID] != null )
h.Remove(Session.SessionID);
Context.Cache[
" online " ] = h;
}
}

 
 
 
 
 
3. 로그 인 및 로그아웃 코드 설정
      로그 인하 기 전에 PreventRepeatLogin () 방법 을 호출 합 니 다. 이 방법 은 사용자 의 중복 로그 인 을 방지 할 수 있 습 니 다. 만약 에 지난번 사용자 가 로그 인 한 시간 이 1 분 이상 초과 되면 모든 admin 디 렉 터 리 의 페이지 를 60 초 이상 닫 았 습 니 다. 지난번 에 로그 인 한 사용자 가 시간 을 초과 하면 로그 인 할 수 있 습 니 다. 60 초 를 초과 하지 않 으 면 사용자 정의 이상 이 생 성 됩 니 다.Cache ["online"] 에 해시 표 가 저장 되 어 있 습 니 다. 해시 표 의 key 는 현재 로그 인 한 사용자 의 SessionID 이 고 Value 는 Array List 입 니 다. 이 Array List 는 두 가지 요소 가 있 습 니 다. 첫 번 째 요 소 는 사용자 가 로그 인 한 이름 입 니 다. 두 번 째 요 소 는 사용자 가 로그 인 한 시간 입 니 다. 그리고 모든 admin 디 렉 터 리 아래 페이지 에서 페이지 를 새로 고 칠 때 현재 로그 인 한 사용자 의 로그 인 시간 을 업데이트 합 니 다.그리고 admin 디 렉 터 리 아래 한 페이지 만 열 려 있 습 니 다. 서버 에 수 동 으로 요청 을 보 내지 않 아 도 로그 인 시간 을 자동 으로 보 냅 니 다. 아래 에 저 는 페이지 기본 클래스 에 함 수 를 써 서 이 를 만 들 었 습 니 다. 사실은 서버 의 부담 을 증가 시 킬 수 있 지만 일정한 상황 에서 도 가능 한 방법 입 니 다.

    
    
    
    
/// <summary>
/// ,
/// </summary>
/// <param name="name"> </param>
private void PreventRepeatLogin( string name)
{
Hashtable h
= (Hashtable)Cache[ " online " ];
if (h != null )
{
IDictionaryEnumerator e1
= h.GetEnumerator();
bool flag = false ;
while (e1.MoveNext())
{
if (( string )((ArrayList)e1.Value)[ 0 ] == name)
{
flag
= true ;
break ;
}
}
if (flag)
{
TimeSpan ts
= System.DateTime.Now.Subtract(Convert.ToDateTime(((ArrayList)e1.Value)[ 1 ]));
if (ts.TotalSeconds < 60 )
throw new oa.cls.MyException( " , , , , ! " );
else
h.Remove(e1.Key);
}
}
else
{
h
= new Hashtable();
}
ArrayList al
= new ArrayList();
al.Add(name);
al.Add(System.DateTime.Now);
h[Session.SessionID]
= al;
if (Cache[ " online " ] == null )
{
Context.Cache.Insert(
" online " , h);
}
else
Cache[
" Online " ] = h;
}

 
사용자 가 로그아웃 할 때 위 에서 언급 한 LogoutCache () 방법 을 호출 합 니 다.
 
 
 
 
 
4. admin 디 렉 터 리 에 있 는 모든 페이지 의 기본 클래스 를 설정 합 니 다.

    
    
    
    
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Collections;
namespace oa.cls
{
public class MyBasePage : System.Web.UI.Page
{
/// <summary>
/// , OA , admin
/// </summary>
protected bool IsAdminDir
{
get
{
return Request.FilePath.IndexOf( " /oa/admin " ) == 0 ;
}
}
/// <summary>
/// session ,
/// </summary>
private void PreventSessionTimeout()
{
if ( ! this .IsAdminDir) return ;
if (Session[ " User_Name " ] == null && this .IsAdminDir)
{
System.Web.Security.FormsAuthentication.SignOut();
this .Alert( " " ,Request.ApplicationPath)
}
}
/// <summary>
/// Cache , OnInit .
/// </summary>
private void UpdateCacheTime()
{
Hashtable h
= (Hashtable)Cache[ " online " ];
if (h != null )
{
((ArrayList)h[Session.SessionID])[
1 ] = DateTime.Now;
}
Cache[
" Online " ] = h;
}
/// <summary>
/// HashTable , OnInit .
/// </summary>
/// <param name="myList"></param>
private void TraceValues(Hashtable myList)
{
IDictionaryEnumerator myEnumerator
= myList.GetEnumerator();
int i = 0 ;
while (myEnumerator.MoveNext())
{
Context.Trace.Write(
" onlineSessionID " + i, myEnumerator.Key.ToString());
ArrayList al
= (ArrayList)myEnumerator.Value;
Context.Trace.Write(
" onlineName " + i, al[ 0 ].ToString());
Context.Trace.Write(
" onlineTime " + i, al[ 1 ].ToString());
TimeSpan ts
= System.DateTime.Now.Subtract(Convert.ToDateTime(al[ 1 ].ToString()));
Context.Trace.Write(
" " , ts.TotalSeconds.ToString());
i
++ ;
}
}
/// <summary>
///
/// </summary>
/// <param name="msg"> </param>
/// <param name="url"> </param>
protected void Alert( string msg, string url)
{
string scriptString = " <script language=JavaScript>alert(/ "" + msg + " / " );location.href=/ "" + url + " / " </script> " ;
if ( ! this .IsStartupScriptRegistered( " alert " ))
this .RegisterStartupScript( " alert " , scriptString);
}
/// <summary>
/// , , , xmlhttp
/// OnInit
/// </summary>
protected void XmlReLoad()
{
System.Text.StringBuilder htmlstr
= new System.Text.StringBuilder();
htmlstr.Append(
" <SCRIPT LANGUAGE=/ " JavaScript/ " > " );
htmlstr.Append(
" function GetMessage(){ " );
htmlstr.Append(
" var xh=new ActiveXObject(/ " Microsoft.XMLHTTP/ " ); " );
htmlstr.Append(
" xh.open(/ " get / " ,window.location,false); " );
htmlstr.Append(
" xh.send(); " );
htmlstr.Append(
" window.setTimeout(/ " GetMessage()/ " ,60000); " );
htmlstr.Append(
" } " );
htmlstr.Append(
" window.onload=GetMessage(); " );
htmlstr.Append(
" </SCRIPT> " );
if ( ! this .IsStartupScriptRegistered( " xmlreload " ))
this .RegisterStartupScript( " alert " , htmlstr.ToString());
}
override protected void OnInit(EventArgs e)
{
base .OnInit(e);
this .PreventSessionTimeout();
this .UpdateCacheTime();
this .XmlReLoad();
if ( this .Cache[ " online " ] != null )
{
this .TraceValues((System.Collections.Hashtable)Cache[ " online " ]);
}
}
}
}

 
 
 
 
 
 
5. 사용자 정의 이상 클래스 를 쓰 려 면 먼저 디 렉 터 리 아래 에 오류 디 스 플레이 페이지 쇼 Err. aspx 를 써 야 합 니 다. 이 페이지 는 전 달 된 검색 문자열 msg 의 값 에 따라 Label 에 오류 정 보 를 표시 합 니 다.

    
    
    
    
using System;
namespace oa.cls
{
/// <summary>
/// MyException 。
/// </summary>
public class MyException : ApplicationException
{
/// <summary>
///
/// </summary>
public MyException()
:
base ()
{
}
/// <summary>
///
/// </summary>
/// <param name="ErrMessage"> </param>
public MyException( string Message)
:
base (Message)
{
System.Web.HttpContext.Current.Response.Redirect(
" ~/ShowErr.aspx?msg= " + Message);
}
/// <summary>
///
/// </summary>
/// <param name="Message"> </param>
/// <param name="InnerException"> </param>
public MyException( string Message, Exception InnerException)
:
base (Message, InnerException)
{
}
}
}

좋은 웹페이지 즐겨찾기