1.数据库表设计:
我这里采用的是MySQL,同时设计了两张表,分别是:user和logins
完整代码下载:https://download.csdn.net/download/ly_linyuan/10334668
(1) user表:
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`password` varchar(300) DEFAULT NULL,
`email` varchar(64) DEFAULT NULL,
`birthday` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
(2) logins表:
DROP TABLE IF EXISTS `persistent_logins`;
CREATE TABLE `persistent_logins` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`series` varchar(300) DEFAULT NULL,
`token` varchar(500) DEFAULT NULL,
`validTime` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
这张表是用户校验用户自动登录的表。设计这张表的原因是我看过一些网上的文章介绍使用cookie自动登录,但是他们基本上都是将用户名、密码、salt等字符串拼接之后md5加密然后保存在cookie中。虽然使用了md5这类非对称加密方式,但是将密码这类关键信息保存在用户端,我觉得是不太靠谱的。因此设计了这张表,将用户名、密码等关键信息加密之后的数据保存到这张表中,在用户的cookie里只保存了没有特殊含义的UUID值以及用户名
表字段的含义:
id: 主键
username : 用户名
series: 用户使用密码登录成功之后获取的一个UUID值,同时用户端保存的cookie记录就是:EncryptionUtil.base64Encode(用户名:此UUID值)
token: 在拦截器中校验是否能够登录的密文,其加密方式是:EncryptionUtil.sha256Hex(用户名 + “” + 密码 + “” + 自动登录失效的时间点的字符串 + “_” + 自定义的salt)
validTime : 自动登录失效的时间,即:这个时间点之后只能重新用用户名、密码登录,如果在重新登录时勾选了“30天内自动登录”则更新该用户在persistent_logins这个表中的自动登录记录
2.SpringMVC的配置文件springmvc-servlet.xml中需要加入拦截器
<!-- 拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 对登录操作进行拦截 -->
<mvc:mapping path="/check.html"/>
<bean class="cn.zifangsky.interceptor.LoginInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<!-- 对/user/**的请求进行拦截 -->
<mvc:mapping path="/user/**"/>
<bean class="cn.zifangsky.interceptor.UserInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
3.这里我们在mapper中加入两个自定义的查询方法
UserMapper.java:
/**
* 根据用户信息查用户详情(登录)
* */
User selectByUser(User user);
/**
* 根据用户名查用户详情
* */
User selectByName(String name);
userMapper.xml:
<select id="selectByName" resultMap="BaseResultMap" parameterType="java.lang.String" >
select
<include refid="Base_Column_List" />
from user
where name = #{name,jdbcType=VARCHAR}
</select>
<select id="selectByUser" resultMap="BaseResultMap" parameterType="cn.zifangsky.model.User" >
select
<include refid="Base_Column_List" />
from user
where name = #{name,jdbcType=VARCHAR} and password = #{password,jdbcType=VARCHAR}
<if test="email != null" >
and email = #{email,jdbcType=VARCHAR}
</if>
<if test="birthday != null" >
and birthday = #{birthday,jdbcType=DATE}
</if>
</select>
loginsMapper.java:
/**
* 通过用户名和UUID值查询自动登录记录
*
* @param username
* 用户名
* @param series
* UUID值
*/
PersistentLogins selectByUsernameAndSeries(@Param("username") String username, @Param("series") String series);
/**
* 通过用户名查询自动登录记录
*
* @param username
* 用户名
*/
PersistentLogins selectByUsername(@Param("username") String username);
loginsMapper.xml:
<select id="selectByUsername" resultMap="BaseResultMap" parameterType="java.lang.String" >
select
<include refid="Base_Column_List" />
from persistent_logins where username = #{username,jdbcType=VARCHAR}
</select>
<select id="selectByUsernameAndSeries" resultMap="BaseResultMap" parameterType="java.util.Map" >
select
<include refid="Base_Column_List" />
from persistent_logins
where username = #{username,jdbcType=VARCHAR} and series = #{series,jdbcType=VARCHAR}
</select>
4.UserService:
/**
* 根据用户名查用户详情
* */
User selectByName(String name);
/**
* 登录
*
* @param user
* 登录的用户信息
* @param rememberme
* 是否记住登录
* @param response
* HttpServletResponse
* @return 根据传递的用户信息在数据库中查询到的用户详情
*/
User login(User user, boolean rememberme, HttpServletResponse response);
/**
* 退出登录
* */
void logout(HttpServletRequest request,HttpServletResponse response);
UserServiceImpl:
@Override
public User selectByName(String name) {
return userMapper.selectByName(name);
}
@Override
public User login(User user, boolean rememberme, HttpServletResponse response) {
User result = new User();
// 如果用户名和密码不为空,执行登录
if (StringUtils.isNotBlank(user.getName()) && StringUtils.isNotBlank(user.getPassword())) {
result = userMapper.selectByUser(user);
// 如果rememberme为true,则保存cookie值,下次自动登录
if (result != null && rememberme == true) {
// 有效期
Calendar cal