从零开始写项目第四篇【登陆注册模块补充】

244 阅读3分钟

tags: 从零开发项目


忘记密码

对于忘记密码这个功能并不难,就跳转到忘记密码页面,让用户输入邮箱,去邮箱所给的超链接修改密码就行了。

记住我功能

本来我是想在登陆的时候勾选“记住我”,那么下次访问的时候,就可以直接访问了(因为我设置了一些链接是需要认证后才能访问的)。

原本是想使用Shiro的rememberMe这个功能的。发现它其实并没有为我们自动实现登陆

具体的参考链接如下:

blog.csdn.net/nsrainbow/a…

查了挺多资料的,发现Shiro的rememberMe这个功能并不好用,但我的系统是基于Shiro来进行开发的。

根据源码的文档说明:



public interface RememberMeAuthenticationToken extends AuthenticationToken {

    /**
     * Returns {@code true} if the submitting user wishes their identity (principal(s)) to be remembered
     * across sessions, {@code false} otherwise.
     *
     * @return {@code true} if the submitting user wishes their identity (principal(s)) to be remembered
     *         across sessions, {@code false} otherwise.
     */
    boolean isRememberMe();

}

只有在当前用户的session(Shiro的Session)存储了已认证的用户,那么才承认当前的用户是已登陆的。

我也想要实现rememberMe这个功能,那么只能手动去弄了

我是通过拦截器来实现的:



public class LoginInterceptor implements HandlerInterceptor {
    @Autowired
    private UserService userService;

    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {



        Subject currentUser = SecurityUtils.getSubject();

        //如果 isAuthenticated 为 false 证明不是登录过的,同时 isRememberd 为true 证明是没登陆直接通过记住我功能进来的
        if (!currentUser.isAuthenticated() && currentUser.isRemembered()) {

            ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();


            //获取session看看是不是空的
            Session session = currentUser.getSession();
            if (session.getAttribute("currentUser") == null) {

                User user = userService.validateUserExist(activeUser.getUsercEmail());

                UsernamePasswordToken token = new UsernamePasswordToken(user.getUserEmail(), activeUser.getPassword(), currentUser.isRemembered());

                //把当前用户放入session
                currentUser.login(token);

                session.setAttribute("currentUser",user);
                //设置会话的过期时间--ms,默认是30分钟,设置负数表示永不过期
                session.setTimeout(-1000l);
			
				//这是httpSession、用户页面获取数据的。
                httpServletRequest.getSession().setAttribute("activeUser", activeUser);

            }
        }

        return true;
    }

    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

那么就可以实现当用户即使关闭了浏览器之后,再次打开浏览器访问我们的页面还是登陆状态!

对登陆注册优化

最开始在页面使用路径都是自己手写:http://localhost:8080/zhongfucheng/这样子的。这样并不通用。想要做得通用的话,那么就要使用变量了。而我又不想使用JSP页面。于是我的项目统一使用freemarker

跳转到某个url的逻辑其实是一样的,没必要为每个跳转都写一个方法。于是我将其抽取出来:


    /**
     * 通用的页面跳转
     *
     * @param folder 模块
     * @param file   具体文件
     * @return
     */
    @RequestMapping("/goURL/{folder}/{file}.do")
    public String goURL(@PathVariable("folder") String folder, @PathVariable("file") String file) {

        return "/" + folder + "/" + file + ".ftl";
    }


对于首页而言我们可以使用监听器来对其进行初始化


public class ProjectListener implements ServletContextListener {



    /**
     * 当项目启动的时候,我们就根据模版生成我们的index页面
     *
     * @param servletContextEvent
     */
    public void contextInitialized(ServletContextEvent servletContextEvent) {

        System.out.println(servletContextEvent.getServletContext().getRealPath("/"));
        try {
            FreeMarkerUtils markerUtils = new FreeMarkerUtils();
            Map map = new HashMap();
            map.put("path", ReadPropertiesUtil.readProp("projectPath"));
            markerUtils.ouputFile("index.ftl", "index.html", map);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

在JavaScript中可能也需要用到http://localhost:8080/zhongfucheng/路径,我们可以使用JavaScript来获取项目的该路径,而不用写死:


    <!--使用JS获取项目根路径-->
    <script>
        var path = "";
        $(function () {
            var strFullPath = window.document.location.href;
            var strPath = window.document.location.pathname;
            var pos = strFullPath.indexOf(strPath);
            var prePath = strFullPath.substring(0, pos);
            var postPath = strPath.substring(0, strPath.substr(1).indexOf('/') + 1);
            path = prePath + postPath;
        });
    </script>

比如我们在获取用户信息的时候就很方便了。

在代码会重复的情况下封装一些常用的Utils,或者使用别人写好的Utils

如果您觉得这篇文章帮助到了您,可以给作者一点鼓励