这里有新鲜出炉的精品教程,程序狗速度看过来!
这篇文章主要介绍了基于 Cookie 使用过滤器实现客户每次访问只登录一次, 需要的朋友可以参考下
相信大家在各大网站都会遇到,登录时,在登录框出现下次免登陆 / 一个月免登陆的类似选项,本文就是讲解如何实现,在这记录一下,也算是做个备忘录合集,如果文中有错,欢迎大家指出
为啥说自登陆一次呢,因为当访问某个页面时,如果第一次自动登录失败时,你下次刷新访问时还再次走自动登录流程,就会出现死循环。
本文代码示例框架为 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 使用过滤器实现客户每次访问只登录一次,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 PHPERZ 网站的支持!
来源: http://www.phperz.com/article/17/0822/337817.html