首頁 > Java > java教程 > 基於cookie使用篩選器實現客戶每次造訪自登陸一次

基於cookie使用篩選器實現客戶每次造訪自登陸一次

巴扎黑
發布: 2017-06-23 16:35:23
原創
1472 人瀏覽過

原創宣言:本文為本人原創作品,絕非他處摘取,轉載請聯絡部落客

相信大家在各大網站都會遇到,登入時,在登入框出現下次免登陸/一個月免登陸的類似選項,本次博文就是講解如何實現,在這記錄一下,也算是做個備忘錄合集,如果文中有錯,歡迎大家指出

為啥說自登陸一次呢,因為當訪問某個頁面時,如果第一次自動登入失敗時,你下次刷新訪問時還再次走自動登入流程,就會出現死循環。

本篇博文程式碼範例框架為Spring MVC,以下就講解實現該功能的需要掌握哪些知識:cookies與篩選器

1.cookies

何為Cookies:Cookies為Web 應用程式保存使用者相關資訊提供了一個有用的方法。例如,當使用者造訪您的網站時,您可以利用 Cookie 來儲存使用者首選項或其他訊息,這樣,當使用者下次再造訪您的網站時,應用程式就可以檢索先前儲存的資訊。

我們來看看如何儲存cookies和如何刪除cookies

  • #儲存cookies

String newUserName = null;
try {
	newUserName = URLEncoder.encode(username, "UTF-8");//把用户名转码,防止用户名是中文,cookies保存中文取出会乱码
} catch (UnsupportedEncodingException e) {
	e.printStackTrace();
}
Cookie nameCookie = new Cookie("username", newUserName);
String pwdMd5Cook = MD5Util.MD5(Pwd);
Cookie pwdCookie = new Cookie("pwd", pwdMd5Cook);// 保存加密后的密码
nameCookie.setMaxAge(60 * 60 * 24 * 365);// 用户名保存一年
pwdCookie.setMaxAge(60 * 60 * 24 * 30);// 密码保存30天
// 发送Cookie信息到浏览器
response.addCookie(nameCookie);
response.addCookie(pwdCookie);
登入後複製

#刪除cookies,刪除很簡單,但值得注意

的時,刪除cookies,跟保存cookies一定要在

同一個控制層

# ,不然會找不到已儲存的cookies,導致刪除不了

Cookie cookie = new Cookie("pwd", null);
cookie.setMaxAge(0);// 删除密码cookie
response.addCookie(cookie);
登入後複製
######2.Filter-過濾器######Filter也稱為過濾器,它是Servlet技術中最實用的技術,Web開發人員透過Filter技術,對web伺服器管理的所有web資源:例如Jsp, Servlet, 靜態圖片檔案或靜態html 檔案等進行攔截,從而實現一些特殊的功能。例如實現URL等級的權限存取控制、過濾敏感詞彙、壓縮回應資訊等一些進階功能。 ######實作方法:繼承###Filter###接口,並實作其doFilter方法。在web.xml檔案中對所寫的filter類別進行註冊,並設定它所能攔截的資源######
<filter>指定一个过滤器。
<filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。
<filter-class>元素用于指定过滤器的完整的限定类名。
<init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值。
在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。
<filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径
<filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字
<url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
<servlet-name>指定过滤器所拦截的Servlet名称。
<filter>
	<filter-name>suicaiFilter</filter-name>
	<filter-class>com.suicai.filter.suicaiFilter</filter-class>
</filter>

<filter-mapping>
	<filter-name>suicaiFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>
登入後複製
######下面看一下實際應用程式碼:######
public class suicaiFilter implements Filter {
	@Override
	public void destroy() {
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req=(HttpServletRequest)request;
		HttpServletResponse res=(HttpServletResponse)response;
		HttpSession session = req.getSession();
		String requestURI = req.getRequestURI();
		String param = req.getQueryString();
		String url = req.getServletPath();
		if(param!=null){
			url = url+"?"+param;
		}
		if(requestURI.contains("js") || requestURI.contains("css") ||  requestURI.contains("images")){
			//不过滤css,js,images等静态资源
			chain.doFilter(request, response);
		}else if(requestURI.contains("/info/")||requestURI.contains("/gys/")){
			//过滤前台访问页面,跟前台个人中心(供应商后台),自动登录一次,登录不成功不进行操作,个人中心登录不成功,则跳到登录页面
			ProviderInfo providerInfo = (ProviderInfo) session.getAttribute("providerInfo_gys");
			String IsAutomaticLogin = (String) session.getAttribute("IsAutomaticLogin");//是否已经走过自动登录流程标识
			if(requestURI.contains("/info/") && !requestURI.contains("/login")){
				//访问门户等不需要必须登录的(登录除外),只尝试登录一次,如果不成功,不进行操作
				if(providerInfo==null && IsAutomaticLogin == null){
					req.getSession().setAttribute("goURL", url);
					res.sendRedirect(req.getContextPath() + "/common/automaticLogin");
				}else if(providerInfo==null && IsAutomaticLogin != null ){
					chain.doFilter(request, response);
				}else{
					chain.doFilter(request, response);
				}
			}else if(requestURI.contains("/gys/")){//访问个人中心,自登陆一次,不成功跳转到登录页面
				if(providerInfo==null && IsAutomaticLogin == null){
					req.getSession().setAttribute("goURL", url);
					res.sendRedirect(req.getContextPath() + "/common/automaticLogin");
				}else if(providerInfo==null && IsAutomaticLogin != null ){
					session.setAttribute("redirectUrl", url);
					res.sendRedirect(req.getContextPath() + "/login.jsp?redirectUrl="+url);
				}else{
					chain.doFilter(request, response);
				}
			}else{
				chain.doFilter(request, response);
			}
		}else{
			//不过滤
			chain.doFilter(request, response);
		}
	}
	@Override
	public void init(FilterConfig arg0) throws ServletException {
	}
}
登入後複製
# #####從程式碼中可知,需要一個是否已經自動登入過的標識(######IsAutomaticLogin######),該識別是在走自動登入時(不管成不成功)保存起來的######3.結合上面提供知識,下面為整體程式碼展示,如發現不對地方,歡迎大家指出######
@Controller
@RequestMapping("/common")
public class CommonController{
	/**
	 * 自动登录方法
	 * @param request
	 * @param response
	 * @param username
	 * @param pwd
	 * @param ProviderInfo 供应商账户信息model
	 * @return
	 */
	@RequestMapping("/automaticLogin")
	public String automaticLogin(HttpServletRequest request,ServletResponse response,@CookieValue(value = "username", required = false) String username,@CookieValue(value = "pwd", required = false) String pwd,ProviderInfo ProviderInfo) {
		// 保存需求登录前的链接
		String goURL = (String) session.getAttribute("goURL");
		if (username == null) {//cookies中没有用户名,肯定不需要自动登录
			session.setAttribute("IsAutomaticLogin", "0");
			return "redirect:" + goURL;
		} else {
			try {
				username = URLDecoder.decode(username, "UTF-8");//转义,防止中文
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		// cookie失效 session一定为空,因为登录时,一定会把用户名保存在cookie中
		if ("".equals(username) || username == null) {// 使用session登录不了,不进行任何操作,不在进入这个方法
			session.setAttribute("IsAutomaticLogin", "0");
			return "redirect:" + goURL;
		} else {
			// cookie中没有密码,判断session为不为空,如果为空,说明没有登录,如果不为空,说明,用户是选择不记住密码登录(所以cookie中没有密码)
			if ("".equals(pwd) || pwd == null) {
				ProviderInfo customer1 = (ProviderInfo) session.getAttribute("providerInfo_gys");
				if (customer1 == null) {// 使用session登录不了,不进行任何操作,不在进入这个方法
					session.setAttribute("IsAutomaticLogin", "0");
					return "redirect:" + goURL;
				} else {
					// 已经登录,不再进入这个方法
					return "redirect:" + goURL;
				}
			} else {
				// cookie中有密码,判断session为不为空,如果为空,说明没有登录,如果不为空,说明已经登录
				ProviderInfo customer1 = (ProviderInfo) session.getAttribute("providerInfo_gys");
				if (customer1 == null) {// 当前没有登录,调用cookies中的用户名跟密码进行登录
					// 进行自动登录操作,登录成功后返回原来页面
					ProviderInfo customer3 = ValidateDate(username);
					customer3.setPwd(pwd);
					customer3.setAccountType(6);
					ProviderInfo customer2 = infoService.login(customer3);//调用登录方法
					if (customer2 == null) {// 自动登录失败,不再进入这个方法
						session.setAttribute("IsAutomaticLogin", "0");
						return "redirect:" + goURL;
					} else {
						// 登陆成功保存客户信息到session
						session.setAttribute("providerInfo_gys",customer2);
						return "redirect:" + goURL;
					}
				} else {
					return "redirect:" + goURL;
				}
			}
		}
	}
	/**
	 * 用户登陆
	 * @param request
	 * @param response
	 * @param cus
	 * @return
	 */
	@RequestMapping("/UserLogin")
	@ResponseBody
	public Map<String, Object> goLogin(HttpServletRequest request,HttpServletResponse response,@ModelAttribute("ProviderInfo") ProviderInfo cus) {
		/*省略一些逻辑判断*/
		cus.setPwd(MD5Util.MD5(Pwd));
		ProviderInfo providerInfo = infoService.login(cus);
		Map<String, Cookie> cookieMap = new HashMap<String, Cookie>();
		if (providerInfo == null) {
			// 登陆失败,重新跳转到登陆页面
			map.put("error", "密码错误");
			return map;
		}else{
			String newUserName = null;
			if (remember_me.equals("1")) {// 有选择一个月免登录
				try {
					newUserName = URLEncoder.encode(username, "UTF-8");
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
				Cookie nameCookie = new Cookie("username", newUserName);
				String pwdMd5Cook = MD5Util.MD5(Pwd);
				Cookie pwdCookie = new Cookie("pwd", pwdMd5Cook);// 保存加密后的密码+"create"
				nameCookie.setMaxAge(60 * 60 * 24 * 365);// 用户名保存一年
				pwdCookie.setMaxAge(60 * 60 * 24 * 30);// 密码保存30天
				// 发送Cookie信息到浏览器
				response.addCookie(nameCookie);
				response.addCookie(pwdCookie);
				session.setAttribute("IsAutomaticLogin",null);
			}else{//没有选择,删除上次可能已经选择自动登录时的密码
				Cookie[] cookies = request.getCookies();
				if (null != cookies) {
					for (Cookie cookie : cookies) {
						cookieMap.put(cookie.getName(), cookie);
					}
				}
				if (cookies != null) {
					for (int i = 0; i < cookies.length; i++) {
						if (cookieMap.containsKey("pwd")) {
							Cookie cookie = new Cookie("pwd", null);
							cookie.setMaxAge(0);// 删除密码cookie
							response.addCookie(cookie);
						}
					}
				}
			}
			// 登陆成功,保存当前user信息,保存客户信息到session
			map.put("ProviderInfo", providerInfo);
			map.put("goURL", session.getAttribute("goURL"));
			session.setAttribute("providerInfo_gys", providerInfo);
			return map;
		}else {
			map.put("error", "该供应商账号不存在");
			return map;
		}
	}
	/**
	 * 注销
	 * @return
	 */
	@RequestMapping("/logout")
	public String logout(HttpServletResponse response) {
		Map<String, Cookie> cookieMap = new HashMap<String, Cookie>();
		Cookie[] cookies = request.getCookies();
		if (null != cookies) {
			for (Cookie cookie : cookies) {
				cookieMap.put(cookie.getName(), cookie);
			}
		}
		if (cookies != null) {
			for (int i = 0; i < cookies.length; i++) {
				if (cookieMap.containsKey("pwd")) {
					Cookie cookie = new Cookie("pwd", null);
					cookie.setMaxAge(0);// 删除密码cookie
					response.addCookie(cookie);
				}
			}
		}
		session.setAttribute("providerInfo_gys", null);
		return "/index";
	}
}
登入後複製
######到此,該功能範例講解全部完成,如有不對的地方,歡迎大家在留言區指出。 ######

以上是基於cookie使用篩選器實現客戶每次造訪自登陸一次的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
上一篇:Spring MVC對日期處理時出現的問題 下一篇:JAVA--assert.notNull
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
最新問題
相關專題
更多>
熱門推薦
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板