나는 최근에 유휴 상태 였고 할 프로젝트가 없었기 때문에 매일 일하는 일에서 발생하는 몇 가지 일반적인 문제를 분류했습니다. 우선, 다중 사용자 로그인 제한 문제에 대해 생각했습니다. 이 문제에 대한 생각을하겠습니다.
관련 판독 값 :
Java 웹 개발 여러 사용자가 반복되는 로그인을 방지하기위한 완벽한 솔루션
1. 디자인 장면
1) 사용자는 동시에 여러 장소에 로그인 할 수 없습니다.
2) 사용자는 A에서 로그인했습니다. 이제 B에서 로그인 할 수 있지만 A (A에서 로그인 한 후 일부 상황으로 인해 사용자가 B에 있었다는 점을 고려하지만 여전히 이전 작업을 계속하려면 시스템에 로그인해야합니다).
3) B에서 A를 압박 한 후에는 A가 다른 작업을 수행 할 때 시스템이 프롬프트를 제공합니다. 사용자는 다른 곳에 로그인합니다. 비밀번호가 자신의 작업이 아닌 경우 비밀번호가 유출 될 수있는 경우 비밀번호를 변경하십시오.
2. 아이디어지도
각 사용자가 로그인하면 일반적으로 사용자가 작업을 수행 할 때 시스템이 사용자의 기본 정보를 쉽게 얻을 수 있도록 사용자 정보를 세션에 저장합니다. 그러나이 세션은 비공개이며 현재 사용자에게만 볼 수 있습니다 (사용자가 다른 세션을 얻는다는 데 동의하는 경우 여러 사용자가 로그인 할 수있는 근본 원인입니다). 그런 다음 질문이옵니다. 사용자가 로그인 할 때 온라인 상태인지 어떻게 알 수 있습니까? 나는 당신이 똑똑하다고 믿고, 당신은 이미 이것이 쉽지 않다고 생각했습니다. 온라인 사용자 정보를 공공 장소에 저장하는 데 문제가 없습니까? 온라인에서 확인한 후 솔루션은 완전히 다르며 대략 두 가지 유형입니다.
1) 데이터베이스에서 온라인 사용자를 식별하십시오
2) 신청서에 저장하십시오
많은 고려 사항 후, 솔루션 1은 많은 어려운 문제 (사용자 비정상 종료 및 향후 수정 상태, 데이터베이스에 대한 자주 액세스가 성능에 영향을 미치는 등)를 해결해야한다는 것을 알게 될 것입니다. 그래서 우리는 솔루션 2를 채택하여 온라인 사용자 정보를 응용 프로그램에 저장했으며 특정 디자인은 다음과 같습니다.
1) 로그인 흐름도
2) 압착 후 작동 흐름도
3. 코드
1) 로그인 방법
@requestmapping (value = "/login", method = requestmethod.post) public String Login (문자열 사용자 이름, 문자열 암호, RedirectAttributes RedirectAttributes, httpservletRequest request) {// 사용자가 온라인 상태이고 처리되었는지 (온라인으로 제거) 문자열 loginlimite = limitlogin.loginlimite (요청, httpservletrequest request redirectattributes, httpservletrequest 요청) 암호는 올바른 문자열 result = userService.Login (사용자 이름, 비밀번호)입니다. if (result.equals ( "success")) {request.getSession (). setAttribute ( "now_user", userervice.findbyUsername (username)); // token을 만들고 문자열 생성 jwttoken = tokenservice.createuserauthtoken (userservice.findbyusername (username); // 생성 tokensystem.out.println (jwttoken); UserauthenticationToken authtoken = tokenservice.retrieveUserauthtoken (jwttoken); // token parses system.out.println (authtoken.isauthenticated ()); system.out.println ( "id =" + UserAuthenticationToken.getCurrentToken (). getUserUuid ()); // 로그인 한 후 저장된 링크로 링크 된 링크로 리디렉션됩니다. Object URL = requestSession (). getAttribute ( "redirect_link"); if (url! = null) {request.getSession (). RemoveAttribute ( "returect_link"); return "return"return "reture"reture "retring";} return "index";} redirectattributes.addflashattribute ( "메시지", 결과); return "retirect :/other/tologin";}2) 이미 온라인인지 확인하려면 로그인
@service @service @transactionalPublic Class LimiteLogin {private static logger log = logger.getLogger (sessionListener.class); 개인 정적 맵 <문자열, 문자열> loginUsermap = new Hashmap = new Hashmap <> (); // 스토리지 개인지도 <String, loginouttime = new Hashmap <> (); // Storage ustrusse @autoried userouseerevice ustronse @autired user user verepry user user verepry user user verepres loginlimite (httpservletrequest 요청, 문자열 사용자 이름) {user user = userervice.findbyusername (username); String sessionId = requestSession (). getId (); for (string key : loginUserMap.keyset ()) {// 사용자가 다른 장소에 로그인했습니다 (key.equals ()). ! loginUsermap.containsValue (sessionId)) {log.info ( "user :" + user.getusername () + "," + dateUtil.dateformat (new date (), "yyyy-mm-dd hh : mm : ss")) + "제외!"); loginout.put (), dateUtil. "yyyy-mm-dd hh : mm : ss")); loginusermap.remove (user.getusername ()); break;}} loginusermap.put (user.getusername (), sessionId); request.getSession (). loginUserMap); request.getSession (). getServletContext (). setAttribute ( "loginoutTime", loginoutTime); return "success";}}3) 로그인 인터셉터 (로그인 페이지로 점프 할 로그인 없음)
공개 클래스 LoginInterceptor 확장 핸들러 interceptorAdapter {@overridepublic boolean prehandle (httpservletrequest request, httpservletrequest responsk, 객체 핸들러) 예외 {httpsession session = request.getsession (); user user = (user) 세션. null) {response.sendRedirect (reture.getContextPath () + "/other/tologin"); return false;} // multi-user 로그인 제한 판결을 받고 즉각적인 메시지 부울 Islogin = false; if (user! = null) {map <string, string> loginusermap = (map <string>). session.getServletContext (). getAttribute ( "loginUsermap"); String SessionId = session.getId (); for (string key : loginUsermap.keyset ()) {// 사용자가 다른 위치에 로그인했습니다 (key.equals (user.getUserName ()). true; break;}}} if (islogin) {map <string, string, loginouttime = (map <string, string>) session.getServletContext (). getAttribute ( "loginoutTime"); session.setAttribute ( "mess", "user :" + user.getusername () + ", in" + loginouttime.get (user. getsername). 다른 곳! "); loginouttime.remove (user.getusername ()); session.getServletContext (). setAttribute ("loginUserMap ", loginouttime); response.sendRedirect (reture.getContextPath () +"/eloply/tologin "); return return.prebhandle (repirt, repord, rander); PosthAndle (httpservletrequest 요청, httpservletresponse 응답, 객체 핸들러, ModelandView ModelandView)는 예외를 {super.posthandle (요청, 응답, 핸들러, ModelAndView);}@reveridepublic void AfterCletion (httpservletrequest Request, Httpservletress 응답, 예외, Extress 응답, 예외적 인 httpervletrestronge). {super.fterCompletion (요청, 응답, 핸들러, Ex);}}4) 세션이 파괴되면 loginusermap에 저장된 키 값 쌍을 지우십시오.
public classsessionListener는 httpsessionListener {private static logger logger.getLogger (sessionListener.class);@attratridePublic void sessionCreated (httpsessionEvent event) {} @OverRidePublic void sessionDestroyed (httpsessionEvent event) {); session.getId (); // 세션이 파괴되면 loginUserMap 사용자 user = (사용자) session.getAttribute ( "now_user"); if (user! = null) {map <String, String> loginUsermap = (map <String, String>)에 저장된 키 값 쌍을 지우십시오. event.getSession (). getServletContext (). getAttribute ( "loginUserMap"); if (loginUserMap.get (user.getUserName ()). equals (sessionId)) {log.info ( "응용 프로그램에서 클린 사용자 :" + user.getusername ()); loginusermap.remove (user.getusername ()); event.getSession (). getServletContext (). setAttribute ( "loginusermap", loginusermap);}}}5) web.xml
<!-세션 리스너 다중 사용자 로그인 제한, 응용 프로그램에 저장된 사용자 로그인 정보를 지우는 동안 세션 정보를 지우기 위해 로그 아웃-> <layer> <layer-class> com.service.limiteLogin.sessionlistener </laisser-class> </largeer>
6) 페이지 코드 (프롬프트를 제공하는 동안 압착 된 사용자의 세션 정보를 지우는 데 사용됩니다. 그렇지 않으면 프롬프트 정보가 항상 표시됩니다)
<script type = "text/javaScript"> $ (document) .ready (function () {var message = '$ {mess}'; if (message! = "" ") {$ .ajax ({type : 'get', async : false, cache : false, url : '/other/clearerusession', datatype : ', data : {}, function (data). {}}); $ ( '#mess'). html (메시지);}}); </script>7) 사용자 세션 코드를 지우십시오
/*** 다중 사용자 로그인 제한, 명확한 세션 정보 (로그인 정보, 프롬프트 정보) ** @param request*@return*/ @responsebody @requestMapping (value = "/clearUserSession") public String clearUsersession (httpservletRequest request) {httpsession httpssession = request.getSession (); // httpsession.invalidate (); httpsession.removeattribute ( "now_user"); httpsession.removeattribute ( "mess"); return "success";}개발 작업은 여기에서 완료됩니다
4. 운영 결과
위의 것은 편집자가 귀하에게 소개 한 Java Multi-User 로그인 제한의 구현 방법입니다. 나는 그것이 당신에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!