English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
최근 .net mvc 프로젝트의 세션 만료 문제에 대해 연구 중이었고, 아래에서 연구 과정을 공유하겠습니다. 참고해 주세요.
최근 .net mvc 프로젝트의 세션 만료 문제를 해결했습니다. 이에 대해 이야기해보겠습니다.
1문제 분석
.net mvc에서 세션이 만료되면 고려해야 할 몇 가지 상황이 있습니다:
• 권한 인증 기반의 Action은 비Ajax 요청을 사용합니다;
• 권한 인증 기반의 Action은 JQuery Ajax 요청을 사용합니다;
• 권한 인증 기반의 Action은 .net mvc가 포장한 Ajax 요청을 사용합니다;
• 권한 인증이 없는 Action은 비Ajax 요청을 사용합니다;
• 권한 인증이 없는 Action은 원시 JQuery Ajax 요청을 사용합니다;
• 권한 인증이 없는 Action은 .net mvc가 포장한 Ajax 요청을 사용합니다;
권한 인증 기반의 Action은 세션이 만료되면 AuthorizeAttribute가 모두 차단하고 HandleUnauthorizedRequest 메서드에서 처리합니다; 권한 인증이 없는 Action은自定义된 필터에서, 새로운 세션과 요청된 세션의 차이를 판단하고 처리해야 합니다.
2권한 인증 기반의 비Ajax 요청
Authorize filter가 다른 기능 필터보다 먼저 실행되므로 여기서 AuthorizeAttribue를 상속받아 HandleUnauthorizedRequest에서 세션 요청을 처리합니다.
public class AuthorizeOfHandleUnAuthorizeAttribute:AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { //session이 만료되면 로그인 페이지로 리디렉션 filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary(new { Controller = "Login", Action = "Login" })); } }
3. 권한 인증 기반의 Ajax 요청
Ajax 요청의 Action은 시스템에서 두 가지 반환 결과를 가지고 있습니다: JsonResult과 PartialViewResult。
•JsonResult은 이론적으로 반환 결과에 session 초과 속성을 추가하여, 클라이언트가 판단할 수 있도록 합니다. 하지만 프로젝트가 완료되었기 때문에, 모든 AJAX 요청에 대해 추가적인 판단 로직을 추가하는 것은 복잡합니다.
서버 코드가 AJAX 요청을 처리하는 방법:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { //ajax 요청 session 초과 처리 if (filterContext.HttpContext.Request.IsAjaxRequest()) { filterContext.HttpContext.Response.AppendHeader("sessionstatus","timeout"); filterContext.HttpContext.Response.End(); return; } filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary(new { Controller = "Login", Action = "Login" })); }
클라이언트 코드(이 처리 방식은 반환 결과가 PartialViewResult인 Action에 적용되지 않습니다):
onSuccess: function (xhr, status) { //응답 헤더를 가져옵니다, sessionstatus, var sessionstatus = xhr.getResponseHeader("sessionstatus"); if (sessionstatus == "timeout") { window.location = "/Login/Login"; } }
•PartialViewResult의 존재로 인해 위의 가설은 부정됩니다. 프로젝트의 대부분의 AJAX 요청은 .net mvc로 포장된 것으로, 지정된 div를 직접 업데이트합니다.
대량의 변경을 피하고, 두 가지 반환 결과를 일관되게 처리하기 위해 다른 방법을 찾았습니다
jQuery.ajaxSetup()
이 함수는 jQuery의 AJAX 요청의 기본 설정 옵션을 변경하는 데 사용됩니다. 이후에 실행된 모든 AJAX 요청이, 해당 옵션 매개변수가 설정되지 않았을 경우, 변경된 기본 설정을 사용합니다.
따라서 우리의 클라이언트 코드는 이렇게 일관되게 처리할 수 있습니다:
//ajax 요청 session 시간 초과 문제 해석 $.ajaxSetup({ complete: function(xmlHttpRequest, textStatus) { complete: function(xmlHttpRequest, textStatus) { if (sessionStatus === "timeout") { window.location = "/Login/Login"; } } });
var sessionStatus = xmlHttpRequest.getResponseHeader("sessionstatus");-本以为到这里就万事大吉啦,结果一不小心又发现一个问题,基于.net mvc的jquery.unobtrusive
ajax封装的ajax请求调用,没有达到拦截处理的效果。经过反复调试无果,最终还是注意到上面那段话
jQuery.ajaxSetup()该函数用于更改jQuery中AJAX请求的默认设置选项。之后执行的所有AJAX请求,如果对应的选项参数没有设置,将使用更改后的默认设置。-这里说的比较明白了,那肯定就是jquery.unobtrusive
ajax封装的时候捣的鬼啦,翻开源码一看果然如此: $.extend(options, {-ajax-type: element.getAttribute(\"data\"), method: element.getAttribute(\"data\"),-ajax-url: element.getAttribute(\"data\"), cache: !!element.getAttribute(\"data\"),-ajax-cache"), beforeSend: function (xhr) { var result; asyncOnBeforeSend(xhr, method); result = getFunction(element.getAttribute(\"data\"));-ajax-begin"), [\"xhr\"]).apply(element, arguments); if (result !== false) { loading.show(duration); } return result; }, complete: function (xhr,status) { loading.hide(duration); getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(element, arguments); }, success: function (data, status, xhr) { asyncOnSuccess(element, data, xhr.getResponseHeader(\"Content\"));-Type") || \"text\"/html"); getFunction(element.getAttribute("data-ajax-success"), [\"data\", \"status\", \"xhr\"]).apply(element, arguments); }, error: function () {}} getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"]).apply(element, arguments); } });
저희는 jquery.unobtrusive를 보았습니다.-ajax는 ajax 요청의 compelete 이벤트를 등록했기 때문에, 우리가 작성한 기본 처리 프로그램이 덮여버렸습니다. 어떤 좋은 방법도 생각나지 않았기 때문에, jquery.unobtrusive를 변경했습니다.-ajax의 소스 코드를 보면:
complete: function (xhr,status) { loading.hide(duration); //ajax 요청 session 시간 초과 문제 해석 var sessionStatus = xhr.getResponseHeader("sessionstatus"); if (sessionStatus === "timeout") { window.location = "/Login/Login"; } getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(element, arguments); },
이제 인증된 ajax 요청의 session失效 문제는 기본적으로 해결되었습니다. 두 가지 결함이 있습니다:
•jquery.unobtrusive를 수정했습니다。-ajax의 소스 코드는 항상 마음에 들지 않았다;
•任何注册了compelete事件的ajax请求,都需要自己处理session问题。
4.无权限任务的Action
无权限认证的Action的Session失效问题,处理代码如下:
if (filterContext.HttpContext.Session != null) { if (filterContext.HttpContext.Session.IsNewSession) { var sessionCookie = filterContext.HttpContext.Request.Headers["Cookie"]; if (sessionCookie != null && sessionCookie.IndexOf("ASP_NET_SessionId", StringComparison.OrdinalIgnoreCase) >= 0) { filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary(new { Controller = "Login", Action = "Login" })); } } }
접근 권한이 없는 Action의 Ajax는 위에 설명한 권한이 있는 처리 방법에 따라 처리할 수 있습니다. 여기서는 코드를 복사하지 않겠습니다. 개인적으로, 접근 권한이 없는 Action 요청은 대부분 session失效 상태를 고려하지 않아도 됩니다.因为这些Action는 대부분 session에서 정보를 가져오지 않으며, 공통 정보만을 쿼리합니다.
5. 남은 문제
이 문제는 기본적으로 해결되었습니다. 그러나 과정에서 모자라게 된奇妙한 문제가 있어 기억해 두겠습니다:
저는 설정 파일을 통해 session 만료 시간을 매우 짧게 설정하여 session失效를 모의하려 했지만, 결과적으로 프로젝트의 기존 프레임워크가 로그인 후 첫 번째 비즈니스 요청에서 session 만료 시간을 무의식적으로 변경하는 것을 발견했습니다.60분, 원인을 찾지 못했습니다. 나중에는 같은 브라우저에서 두 개의 탭을 엽니다. 시스템에 로그인한 후, 한 개의 탭에서 방출하는 메서드를 모의합니다.
위에 설명한 것은 저가 여러분께 소개한 .net mvc session失效 문제이며, 여러분에게 도움이 되길 바랍니다. 만약 여러분이 어떤 의문이 있다면, 댓글을 달아 주시고, 저는 즉시 답변을 드리겠습니다. 또한, 여러분이 나아라 튜토리얼 웹사이트에 대한 지원에 감사드립니다!
고지사항: 본문의 내용은 인터넷에서 가져왔으며, 저작권자는 본사가 소유하고 있으며, 인터넷 사용자가 자발적으로 기여하고 자신의 주체적으로 업로드한 내용이며, 본 사이트는 저작권을 소유하고 있지 않으며, 인공 편집을 하지 않았으며, 관련 법적 책임을 부담하지 않습니다. 저작권 문제가 있을 경우 notice#w로 이메일을 보내 주시기 바랍니다.3codebox.com(댓글을 작성할 때는 #을 @으로 변경하여 신고하시고, 관련 증거를 제공해 주시면, 해당 내용이 실제로 위반되는 것이 확인되면,本站이 즉시 위반된 내용을 삭제할 것입니다。)