spring+redis+Interceptor拦截器实现登录功能

时间:2024-10-05 22:01:21
这里要完成的功能有以下几点:

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