这里要完成的功能有以下几点:
1. 登录时用户名密码的验证
2. 登录成功后用户数据存到session中
3. 使用cookie实现3天免登陆效果
4. 使用rides存取用户信息
5. 使用拦截器过滤非法请求
6. 退出登录清空session,cookie,rides
1.登录的用户名密码从js接收传到controller调用service方法做处理,这里直接写service中的处理过程:
1. 登录时根据邮箱和密码进行登录,根据查询结果判断邮箱验证有没有激活决定能否登录
2. 登录验证没有问题后将用户信息存储到session中方便使用
3. 登录成功将用户信息转换成gson格式存储在rides中,需要gson依赖
4. 用一个随机字符串作为key,转化成gson的user对象作为value,存入rides中,方面后边取用
5. 创建一个cookie以键值对的方式只存rides中对象数据的key方便从rides中取值,也保证了cookie的安全
6. 给cookie设置失效时间和作用域范围然后写入cookie
7. 这样就实现了登录功能
@Service
public class UserServiceImp extends BaseServiceImpl<User> implements UserService {
@Autowired
UserMapper usermapper;
//注入一个redis的连接池对象
@Autowired
JedisPool jedisPool;
//登录功能根据邮箱密码和激活状态
@Override
public int selectByEmailaPwdaState(User user,HttpSession httpsession,HttpServletResponse response) {
String password = MyUtil.md5(user.getPassword());
String email = user.getEmail();
User user1 = usermapper.selectByEmailaPwdaState(email, password);
if(user1!=null){
if(user1.getActivationState()==1){
httpsession.setAttribute("user", user1);
//登录成功后将对象存到redis中,转换成gson字符串格式,cookie从redis中获取对象
//通过连接池对象获得一个连接,相当于从连接池中拿一个连接
Jedis jedis = jedisPool.getResource();
Gson gson = new Gson();//创建gson对象
//key用随机字符串将转化成json格式的对象存入redis
String key = UUID.randomUUID().toString();
jedis.setex("SESSION:"+key, 60*60*24*3, gson.toJson(user1));
//登录成功后存入cookie,实现免登陆效果
//token授权的意思,key随机字符用来调用redis中对象字符串
Cookie cookie = new Cookie("token",key);//创建cookie,里面存redis的key
cookie.setMaxAge(60*60*24*3);//设置cookie的失效时间
cookie.setPath("/");//设置cookie作用域在当前项目下
response.addCookie(cookie);//写入cookie
return 1;//用户存在状态为1
}else if(user1.getActivationState()==0){
return 2;//用户存在状态为0
}
}
return 0;//用户不存在
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
3.配置rides和gson的依赖包,以及在中配置rides的连接池,和rides的properties文件的相关值
<!-- jedis工具包 -->
<dependency>
<groupId></groupId>
<artifactId>jedis</artifactId>
<version>2.4.2</version>
</dependency>
<!-- gson依赖,用于把对象存在redis中转换格式-->
<dependency>
<groupId></groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
<!-- Redis连接池的配置 -->
<bean id="jedisPoolConfig" class="">
<property name="maxTotal" value="${}" />
<property name="maxIdle" value="${}" />
<property name="minIdle" value="${}" />
<property name="maxWaitMillis" value="${}" />
<property name="testOnBorrow" value="${}" />
<property name="testOnReturn" value="${}" />
</bean>
<!-- 在java中需要调用redis的地方注入jedisPool这个连接池对象 -->
<bean id="jedisPool" class="">
<constructor-arg index="0" ref="jedisPoolConfig" />
<constructor-arg index="1" value="${}" />
<constructor-arg index="2" value="${}" />
<constructor-arg index="3" value="${}" />
<!--Redis密码 -->
<!--<constructor-arg index="4" value="${}" /> -->
</bean>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
properties文件中的相关值
=192.168.1.238
=6379
=
=5000
=300
=250
=200
=3000
=true
=true
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
4.拦截器过滤非法请求,在拦截器中需要从rides中取值用来cookie免登陆效果
中拦截器的配置文件,以及拦截器的映射文件的bean创建
<!-- spring拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 需要拦截的请求 /**代表拦截所有请求 -->
<mvc:mapping path="/**"/>
<!-- 排除不需要拦截的请求 -->
<mvc:exclude-mapping path="/static/js/**"/>
<mvc:exclude-mapping path="/static/css/**"/>
<mvc:exclude-mapping path="/"/>
<mvc:exclude-mapping path="/user/login"/>
<bean class=""></bean>
</mvc:interceptor>
</mvc:interceptors>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
拦截器中在请求之前拦截判断
1. 这里用到了rides,需要先创建一个连接池对象获取一个连接
2. 得到所有的cookie遍历看有没有key键名字叫token的,指向的是redis中登录时存的user对象的key
3. 有的话取出token对应的key键看是否能从rides中查出响应的数据结果
4. 如果能说明这个用户是存在的可以放行
5. 但是由于退出的时候session清空了,这里放行前需要再把rides中的gson数据格式转换成user对象存到session中
6. 其他情况统统拦截直接跳转到登录页面
拦截器
public class Interceptors implements HandlerInterceptor{
//注入一个redis的连接池对象
@Autowired
JedisPool jedisPool;
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {System.out.println("方法结束之后");}
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {System.out.println("方法调用之后");}
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object arg2) throws Exception {
System.out.println("请求之前拦截");
//通过连接池对象获得一个连接,相当于从连接池中拿一个连接
Jedis jedis = jedisPool.getResource();
//根据cookie来判断是否登录
//得到所有的cookie
Cookie[] cookies = req.getCookies();
for(Cookie cookie : cookies){
//查看cookie中有没有叫token的授权码key,指向的是redis中登录时存的user对象
if(cookie.getName().equals("token")){
//如果有取出token中的key授权码value去核对
String token = cookie.getValue();
//在redis中看该授权码对应的信息是否正确
String result = jedis.get("SESSION:"+token);
if(result==null){
//如果在redis中没有对应的信息跳转到登录页面
resp.sendRedirect("/");
return false;
}else{
//不等于空说明已登录,通过
//因为是免登陆效果当退出的时候session已经被清空,需要在这里重新把对象存到session
Gson gson = new Gson();
User user = gson.fromJson(result, User.class);
req.getSession().setAttribute("user", user);
return true;
}
}
}
//如果cookie中没有存token也跳转到登录页面
resp.sendRedirect("/");
return false;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
5.退出登录功能:
1. 清空session
2. 遍历cookie找到cookie中token对应的key从rides中删除
3. 把cookie覆盖
@Override
public void logout(HttpServletRequest request,HttpServletResponse response) {
//清空session
request.getSession().invalidate();
//清空cookie
Cookie[] cookies = request.getCookies();
for(Cookie cookie : cookies){
if(cookie.getName().equals("token")){
String value = cookie.getValue();
//清除redis,删除掉某个key
Jedis jedis = jedisPool.getResource();
jedis.del("SESSION:"+value);
//将cookie失效时间设置成0,从新写入cookie将之前的覆盖掉
cookie.setMaxAge(0);
response.addCookie(cookie);
return;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
//退出登录
@RequestMapping("logout")
public String getall(HttpServletRequest request,HttpServletResponse response){
us.logout(request, response);
return "redirect:/";
}
- 1
- 2
- 3
- 4
- 5
- 6