springmvc中使用Interceptor+Cookie实现自动登录

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
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值