使用Spring3 實現使用者登入以及許可權認證
這裡我就簡單介紹一下,我在實現的時候處理的一些主要的實現。
1.使用者登入
<form action="loginAction.do" method="post"> <div class="header"><h2 class="logo png"></h2> </div> <ul> <li><label>使用者名稱</label><input name="username" type="text" class="text"/></li> <li/> <li><label>密 碼</label><input name="password" type="password" class="text" /></li> <li/> <li class="submits"> <input class="submit" type="submit" value="登入" /> </li> </ul> <div class="copyright"> 2013 - 2014 |</div></form>
以上是前台頁面,背景就是一個簡單的邏輯實現:
@RequestMapping(value="loginAction.do", method=RequestMethod.POST)public ModelAndView loginAction(@RequestParam(value="username") String username, @RequestParam(value="password") String password, HttpSession session, HttpServletResponse resp, @RequestParam(value="savetime", required=false) String savetime) {session.removeAttribute(LogConstant.LOGIN_MESSAGE);SystemUserDataBean user = userDao.getSystemUserByUserName(username);ModelAndView view = null;if(user == null) {view = new ModelAndView(new RedirectView("login.html"));session.setAttribute(LogConstant.LOGIN_MESSAGE, "使用者名稱不正確");return view;}boolean isPasswordCorrect = EncryptionUtil.compareSHA(password, user.getPassword());if(isPasswordCorrect){session.setAttribute(LogConstant.CURRENT_USER, username);} else{view = new ModelAndView(new RedirectView("login.html"));session.setAttribute(LogConstant.LOGIN_MESSAGE, "密碼不正確");}return view;}2.登入資訊
這裡,在登入頁面有一段javascript,來顯示密碼錯誤等資訊:
<script type="text/javascript">var login_username_info = '<%=request.getSession().getAttribute("currentUser") == null ? "" : request.getSession().getAttribute("currentUser")%>';var login_message_info = '<%=request.getSession().getAttribute("login_message") == null ? "" : request.getSession().getAttribute("login_message")%>';if(login_message_info != null && login_message_info != ''){alert(login_message_info);}</script>
3.攔截未登入使用者的請求
這裡,從頁面和後台實現了雙重攔截:
頁面代碼如下:
<%if(session.getAttribute("currentUser")==null){%>window.parent.location='login.html';<%}%>
後台是一個攔截器(servlet-config.xml):
<!-- 攔截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/*.do" /> <bean class="com..log.report.interceptor.AccessStatisticsIntceptor" /> </mvc:interceptor> </mvc:interceptors>
攔截器的實現是
import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;public class AccessStatisticsIntceptor implements HandlerInterceptor {@Overridepublic void afterCompletion(HttpServletRequest arg0,HttpServletResponse arg1, Object arg2, Exception arg3)throws Exception {// TODO Auto-generated method stub}@Overridepublic void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,Object arg2, ModelAndView arg3) throws Exception {// TODO Auto-generated method stub}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object obj) throws Exception {String uri = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/") +1); if(!AuthorityController.isAuthorized(uri, request.getSession())) { //校正失敗 return false;// throw new CustomException(LogConstant.USER_NOT_LOGIN); } return true; }
具體如何校正的,會根據使用者的許可權,就不介紹了
4.返回未登入前訪問的頁面
首先在頁面添加一段指令碼,使用jquery去訪問後台
var page = "";var loc = decodeURIComponent(window.parent.location);var start = loc.indexOf("Log/") + 8;var end = loc.indexOf(".html");page = loc.substr(start, end-start);if(page != null && page != '') {alert(page);$.ajax({type : "get",url : "setPreviousPageAction.do?previousPage=" + page + ".html",success : function(msg){}});}
然後,後台有記錄這個頁面:
@RequestMapping(value="setPreviousPageAction.do")public void setPreviousPageAction(@RequestParam(value="previousPage") String previousPage, HttpSession session){ session.setAttribute(LogConstant.PREVIOUS_PAGE, previousPage);}
在登入完成後,返回這個頁面即可。
5.儲存使用者名稱密碼
登入頁面提供一個儲存下拉框:
<select class="save_login" id="savetime" name="savetime"><option selected value="0">不儲存</option><option value="1">儲存一天</option><option value="2">儲存一月</option><option value="3">儲存一年</option></select>
後台在登入時會操作,將資訊儲存在cookie中:
if(savetime != null) { //儲存使用者在Cookieint savetime_value = savetime != null ? Integer.valueOf(savetime) : 0;int time = 0;if(savetime_value == 1) { //記住一天time = 60 * 60 * 24;} else if(savetime_value == 2) { //記住一月time = 60 * 60 * 24 * 30;} else if(savetime_value == 2) { //記住一年time = 60 * 60 * 24 * 365;}Cookie cid = new Cookie(LogConstant.LOG_USERNAME, username);cid.setMaxAge(time);Cookie cpwd = new Cookie(LogConstant.LOG_PASSWORD, password);cpwd.setMaxAge(time);resp.addCookie(cid);resp.addCookie(cpwd);}
前台在發現使用者未登入時,會取出cookie中的資料去登入:
if(session.getAttribute("currentUser")==null){Cookie[] cookies = request.getCookies();String username = null;String password = null;for(Cookie cookie : cookies) {if(cookie.getName().equals("log_username")) {username = cookie.getValue();} else if(cookie.getName().equals("log_password")) {password = cookie.getValue();}}if(username != null && password != null) {%>$.ajax({type : "post",url : "loginByCookieAction.do",data:"username=" + "<%=username%>"+ "&password=" + "<%=password%>",success : function(msg){if(msg.status == 'success')window.parent.location.reload();else if(msg.status == 'failed')gotoLoginPage();}});<%} else {%>gotoLoginPage();<%}...
以上就列出了我在解決登入相關問題的方法,代碼有點長,就沒有全部列出。