忘记密码(密码找回)
忘记密码(密码找回)这个功能可以说是目前所有为别人提供服务的软件系统都具备的基础功能啦!很普遍,因为总会有人忘记了自己的密码,这个时候就会选择忘记密码功能,根据自己注册账号时使用的证件号码(比如邮箱地址、手机号码、身份证号等)以某种方式(比如发邮件、发送手机短信息等)来重新设置密码!这样我们忘记了密码的账号就又可以继续使用啦!当然如果账号、密码、证件号所有东西都忘了的话,那你还是重新注册一个账号吧!
密码找回这个功能很小,也很基础,但是不可缺少。原理也很简单,不过会根据不同的业务场景选择不同的密码找回流程。不过原理都大同小异,目前主要有两种方式找回密码(发送邮件的方式、和发送短信息的方式),这两种方式还是有所差别的,这里我们就选择使用发送邮件的方式来实现密码找回功能吧!(因为发邮件的方式免费!!!嘻嘻)。为了实现这个功能,我们之前专门写了一篇文章来了解在程序中发送邮件的简单运用,所以实现这个功能对我们来说只剩下需要了解密码找回流程的问题啦!
那么密码找回的流程应该是怎样的呢?我们这里就搞一个简单的密码找回流程吧!因为根据不同的业务场景,我们的找回流程也应该相应的调整。从而达到严谨安全的目的。
先来看看我们的密码找回的简单流程。
1,点击忘记密码按钮
2,来的密码找回页面
3,让用户输入注册时的邮箱账号,并点击确定(控制器收到请求,拿到邮箱地址,给这个邮箱发送重置密码的连接)给邮箱发送重置密码连接
4,用户登录注册时使用的邮箱中,点击收到邮件中的重置密码链接地址来到重置密码页面
5,提交重置密码请求,确定修改新密码;
整个密码找回之分了这简单的五个步骤,比较简单,不过这里有两个地方需要注意。
一、步骤3的时候,我们会给用户提供的邮箱发送一封邮件,邮件中有我们修改密码的请求地址,这个请求地址用户只要点击就会跳转到修改密码页面。可是我们怎么才能知道是哪个用户要修改密码呢?我们会在邮件中的请求地址中添加上用户的身份信息,用户点击请求地址跳转到修改密码页面后,这个身份信息也会跟到修改密码页面并也新密码一并提交到后台让我们修改用户密码。不过这个身份信息肯定是不能使用用户id的,如果把用户id添加到修改密码的请求地址中,那么所有人就都可以看到用户的用户id啦,这样很危险。所有我们在这里需要创建一个临时的、一次性的token信息来跟用户id进行绑定,在发送邮件时临时生成,修改密码完成后就删除这个token。这样就算是同一个用户每次修改密码时使用的token信息也会不同,可以起到一定的保密作用。
二、步骤5的时候,我们后台修改密码完成后,应该要删除跟用户id绑定的token信息,这样可以保证这个token是一次性的。就算在修改完密码后被别人拿到了token信息,也没有用。当然,我们也可以为这个token添加一个有效时间,来让token更加安全。
好,接下来我们就来实现一下密码找回这个功能吧!
添加忘记密码页面,点击登录页面的忘记密码按钮来到忘记密码页面。
页面内容很简单,只有一个邮箱地址输入框就行,使用登录页面修改一下就好了。
因为只是一个简单的页面跳转,嫌麻烦就没有写controller程序,只是在springmvc配置文件中添加一个简单的配置来进行页面跳转。
点击忘记密码后跳转到忘记密码页面,添加邮箱地址后点击确定发送发送邮件请求。
在controller控制器中处理忘记密码页面点击发送邮件的请求。处理后返回发送邮件成功页面。
在service中添加发送邮件的功能。先判断用户填写的邮箱是否存在,如果不存在就不用发邮件了。如果存在创建token,根据邮箱找到用户id,再将token保存到t_user_token表中也用户id进行绑定。t_user_token表是我们新创建的一张数据表,就是为了保存用户id与token信息,因为用户表中没有token列,如果添加token列改变用户表结构的话修改的地方太多,代价太大。所以就创建了t_user_token。主要还是前期设计表结构时没有考虑周到呀!t_user_token表的正删改查这里就不说了,都是自动生成的,很简单,直接使用就可以了。
数据库表中保存好对应的token信息后,就可以发送数据啦!这里我是使用我自己163邮箱账号为发送者(记得在程序中使用163的邮箱时需要申请权限哦!!)
将包含token信息的修改密码请求地址作为邮件内容,发送到用户填写的指定邮箱中,就ok啦!
发送邮件后跳转到发送邮件成功页面。并且可以查看邮件。
好,token生成了,邮件也成功发送了。接下来就到了修改密码啦 !
点击邮件中的链接,发送重置密码请求。来到重置密码页面。那么重置哪个用户的密码呢?当然是根据邮件链接中的token信息来分辨重置哪个用户的密码啦!
在页面中添加一个隐藏的出入框,输入框的值就是邮件链接中的token信息,这样在提交修改密码form表单的时候,就可以将token信息和密码信息一同提交到后台的controller更新密码请求处理方法中啦。
设置新的密码,点击确认重置发送更新密码请求。并在后台controller中处理这个更新密码的请求。
更新用户的密码后,记得要清除token信息,因为token是一次性的验证信息,同一个token信息不应该修改两次用户密码。
在dao中自定义根据token信息更新密码方法。
编写sql语句。
点击确定重置后修改密码,删除token,并跳转到重置密码成功页面。
到这里重置密码就完成啦。接下来我们就用新的密码重新登录一下,试试可不可以登录。
成功了!!!!
这个功能实现的比较粗糙,很多逻辑不够严谨,大家参考一下就可以啦!
记住我(自动登录)
那么接下来呢!我们再来实现一下自动登录这个功能。自动登录这个功能相对比较简单,主要是需要使用cookie来保存用户信息,用于自动登录时的身份验证。
自动登录这个功能大体可以分为两步骤:
一、当用户第一次勾选了自动登录复选框,并点击登录后,后台的controller在处理登录请求时,应该在用户的身份验证信息正确后还要将用户的身份信息再保存一份到客户端的浏览器中(用设置cookie的形式)。这样客户端浏览器中就拥有了之前选中自动登录用户的用户信息啦,以供下次的自动登录使用。不过呢!在我们向cookie中设置用户的身份信息时,出于安全考虑还是不要直接保存用户名与密码的好!我们应该也像在忘记密码时那样用一个随机且唯一的token与用户绑定后,在cookie中保存这个token,这个token就是这个用户的身份标识。
二、当用户再次登录的时候,在登录页面login.jsp中应该首先进行自动登录检查(1,用户是否带了自动登录的cookie。2,如果带了,查出用户信息保存到session中《为什么保存到session中?因为登录页面之后的主页面需要的用户信息是从session中拿的,之前就是这么实现的》并且登录《就是直接跳转到登录页面之后的主页面》。3,如果没带,就正常显示登录页面。)。
当然在进行自动登录检查 2)的时候,向服务端查询用户信息时有可能会比较耗时,那么每一次自动登录时都要等待查询几秒的话,用户体验会比较差,为了增加用户体验可以使用缓存技术(redis等)。
大概流程我们了解了。接下来我们就来实现一下吧。
现在登录页面添加一个自动登录的单选框。
就下来,我们需要修改以前处理登录功能的controller,在登录时不光要校验用户名与密码,还要判断是否使用了自动登录功能,如果使用了自动登录功能,我们就要将登录成功的用户身份信息保存到客户端浏览器的cookie中,用于下次用户登录时可以自动登录。
出于安全考虑,这里在向客户端浏览器保存用户的身份cookie时,使用的也是一个随机生成的token,在数据库中创建这个token与用户的对应关系,这样一个token信息就相当于用户信息啦!
这里有一个地方需要注意一下!!!就是我们要记得设置cookie的访问路径cookie.setPath(),而且必须设置路径为当前本工程的路径,否则在客户端浏览器是找不到我们设置的cookie信息的。原因是因为springMVC出于安全考虑,只允许我们设置当前工程路径的cookie,否则该cookie就会被springMVC偷偷的删除掉。而如果我们自己不设置cookie的路径的话,cookie自己会为自己带上一个默认的访问路径 “ / ”。这样就会被删除!!!!
在service中判断应该更新用户的token或者添加token。
哎,由于需要将用户与自动登录的这个token关联起来,但是之前的数据库表中没有考虑到这个问题,所以需新创建表来对应这个关系,就将这个对应关系放在前面忘记密码token对应的表中吧。所以我们需要修改表t_user_token,并且重新逆向生成t_user_token表。好烦!!
好了,已经将用户的身份token信息保存到了客户端浏览器中的cookie中。接下来我们在下次登陆的时候,使用这个信息来完成自动登录。
那么如何在下次登录的时候实现自动登录呢?就是在登录页面login.jsp中一开始的位置添加脚本,在脚本中取得我们在cookie中保存的token用户信息,再根据这个token去查询缓存或者数据库,看看跟这个token绑定的用户信息是否存在。如果存在就说明是我们之前正确登录并点击了自动登录的用户,那么就可以跳转到登录之后的页面main.jsp来完成自动登录啦。如果这个token在缓存和数据库中都查询不到用户信息,那么就说明这个token是有问题的,或者不是我们之前正确登录并点击了自动登录的用户。那么就不用做任何处理,直接显示登录页面login.jsp就可以啦。
这样自动登录功能就算完成啦 !不过这里还是有个地方需要注意一下。就是我们在根据自动登录的token查询用户信息成功后,直接跳转到登录之后的页面main.jsp时需要注意。这个main.jsp页面是在工程的WEB_INF目录下的(WEB_INF目录下的页面是不可以直接被访问的,只能通过controller访问)。我们直接重定向sendRedirect访问main.jsp页面是不允许的。所以这里我sendRedirect访问main.html,并新建controller的请求处理类DespatcherController来处理main.html这个请求,在这个请求的处理方法中去访问main.jsp页面就可以啦!!嘻嘻!!因为懒所以有点投机取巧呀!
好了,我们运行系统试试吧。
在登录时选中自动登录单选框。点击登录。
成功登陆后,退出到首页,重新登录。
点击去登录页面,会看到自动发送main.html的请求,说明根据用户的token取得用户信息成功啦。
这样自动登录就完成啦!
这里的自动登录功能很简单,也很简陋。只是用于学习,大家在实现这个功能的时候,根据自己项目的需求做相应修改就好。
这里附上代码下载地址,用于需要的时候查阅:https://download.csdn.net/download/qq_25106373/11233448
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
到这里我们的众筹网项目中的后台manager程序的相关知识就完成啦,没有实现的都是一些重复性的增删改查功能,多多练习就好,没有必要在这里浪费篇幅。
众筹系统架构重构
接下来呢!我们就要去实现给广大用户使用的前台功能啦!不过,前台的程序的基础结构跟后台有点不太一样。由于后台manager程序是给管理人员使用的系统,比较小众,并且访问的方式也比较单一(统一使用电脑网页端访问)。所以后台的服务多数都是返回直接跳转到页面的方式。可是前台给用户使用的系统不同,前台的用户会很多,访问方式也多样化(比如,电脑网页端、手机app端、平板电脑等),这样我们就不能再直接返回页面给客户端程序啦。我们应该统一返回json数据给客户端,让客户端自己去解析返回数据并显示。这样就可以实现一套服务程序同时为多端客户端提供服务啦!
这样我们就需要在我们的系统中再创建war项目,来单独为前台用户提供可独立运行的服务。先来看看我们整个众筹平台的基础结构吧。
上图中的scw-portal项目与scw-restapi项目是在整个众筹平台系统重新创建的两个war项目。scw-portal只负责处理网页端前台用户跳转页面的请求,至于页面中的数据都是从scw-restapi请求获得的。scw-restapi负责处理并返回所有客户端需要的json数据。scw-restapi项目、scw-portal项目和scw-manager项目这三个项目都是可以运行的war项目。
scw-manager项目不用多说,只为众筹平台的管理人员提供服务,也就是后台程序。
scw-restapi项目是为所有前台用户的客户端提供,统一返回json数据的服务。
scw-portal项目只负责处理网页端前台用户跳转页面的请求。由于手机移动app有自己的页面,不需要服务端返回页面。但pc网页端不同,客户端是浏览器,无法保存页面,所有需要先向scw-portal发送跳转页面的请求,然后再获取需要的json数据。
创建这两个项目。
添加spring、springMVC并编写配置文件。scw-portal项目和scw-restapi项目作为可以独立部署和独立运行的前台用户服务,应该自己单独拥有一整套的pojo和dao。
同样的方式创建scw-restapi项目。
创建好了值,试一下。
添加测试使用的controller处理类test1,返回json数据。
浏览器访问,并成功返回json数据。
这里我使用的是火狐浏览器,可以正确的显示json数据。谷歌浏览器也是可以的。但是我的IE浏览器就不行啦?提示让我下载这个json数据。为什么呢???
返回json数据低版本浏览器显示下载问题
原因是我的IE浏览器版本太低!!!后台返回json数据时的响应头是Content-Type: application/json;charset=UTF-8,可是我的IE并不识别application/json类型,所以就出现了无法正常显示的问题。那么如何解决呢???
既然找到了原因,解决起来就简单啦!将响应头的类型Content-Type:修改为IE可以识别的不就可以了嘛!!!
这里我们的修改方法也很简单。
修改springmvc.xml配置文件就可以啦。
修改后再试试。。
ok,就这么解决啦。。。