思路:使用Cookie来
1、client发送username和password到server
2、server验证成功后, 写cookie到client,然后返回ok的json, 其中cookie的key要存储在redis中,value就是用户信息, 并且要设置key的过期时间,如:60分钟
3、client收到ok后, 进行相应的业务操作, 以后每次请求server都会自动带上cookie, 不用你写代码
4、server端的filter(你肯定用filter来实现)中会每次验证传过来的cookie的key在redis中是否存在, 有就代表登录成功过可以操作, 没有就返回错误标识注意: 在登录成功后, 每次调用服务器接口时候, 都要为redis的key进行续期,如60分钟
5、当redis的key超过60分钟, 自己会删除这个key, 那么再次请求server时, 就会收到需要登录的返回值
6、当用户主动退出系统的时候, 也要在server中删除redis的key
1.创建项目
2.登录表单
在src/resource/templates下新建
1、client发送username和password到serve
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<h1>登录</h1>
<form action="/login" method="post">
账号:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/><br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
LoginCtroller.java
2、server验证成功后, 写cookie到client,然后返回ok的json, 其中cookie的key要存储在redis中,value就是用户信息, 并且要设置key的过期时间,如:60分钟
package com.xiaomin.login_redis.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xiaomin.login_redis.constant.CookieConstant;
import com.xiaomin.login_redis.constant.RedisConstant;
import com.xiaomin.login_redis.enums.ResultEnum;
import com.xiaomin.login_redis.pojo.Userinfo;
import com.xiaomin.login_redis.pojo.vo.ResultVo;
import com.xiaomin.login_redis.service.UserinfoService;
import com.xiaomin.login_redis.utils.CookieUtil;
import com.xiaomin.login_redis.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* @create 2020-04-07 17:13
*/
@RestController
public class LoginController {
@Autowired
private UserinfoService userinfoService;
@Autowired
private RedisTemplate redisTemplate;
/**
* 用户登录
* @return
*/
@PostMapping("/login")
public ResultVo login(String username, String password, HttpServletResponse response){
//1、获取用户名和密码进行非空判断
if(username.trim().equals("") || password.trim().equals("")){
return ResultUtil.build(ResultEnum.NAME_AND_PWD_ISNULL,"");
}
//2、根据用户名查询用户信息
Userinfo userinfo = userinfoService.getOne(new QueryWrapper<Userinfo>().eq("username", username.trim()));
if(userinfo==null){
return ResultUtil.build(ResultEnum.NAME_ISNULL,"");
}
//3、进行密码比对
if(!userinfo.getPassword().trim().equals(password)){
return ResultUtil.build(ResultEnum.NAME_AND_PWD_ERROR,"");
}
//4、用户对象转换成json串,注意:密码需要设置为空,不能给
userinfo.setPassword(null);
String user = JSON.toJSONString(userinfo);
//5、生成uuid
String uuid = UUID.randomUUID().toString().replace("-", "");
//6、创建cookie,客户端保存cookie
CookieUtil.setCookie(response, CookieConstant.TOKEN,uuid);
//7、把用户信息存入redis
redisTemplate.opsForValue().set(String.format(RedisConstant.TOKEN,uuid),user);
//8、设置过期时间
redisTemplate.expire(String.format(RedisConstant.TOKEN,uuid), RedisConstant.EXPIRE, TimeUnit.SECONDS);
//9、登录成功,返回用户信息
return ResultUtil.success(userinfo);
}
}
LoginAspect.java
这里使用AOP来进行切面
3、client收到ok后, 进行相应的业务操作, 以后每次请求server都会自动带上cookie, 不用你写代码
4、server端的filter(你肯定用filter来实现)中会每次验证传过来的cookie的key在redis中是否存在, 有就代表登录成功过可以操作, 没有就返回错误标识注意: 在登录成功后, 每次调用服务器接口时候, 都要为redis的key进行续期,如60分钟
package com.xiaomin.login_redis.aspect;
import com.xiaomin.login_redis.constant.CookieConstant;
import com.xiaomin.login_redis.constant.RedisConstant;
import com.xiaomin.login_redis.exception.AuthorizeException;
import com.xiaomin.login_redis.utils.CookieUtil;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
/**
* 校验用户是否登录
* @author 晓敏
* @create 2020-04-07 16:42
*/
@Aspect
@Component
public class LoginAspect {
private Logger logger = LoggerFactory.getLogger(LoginAspect.class);
@Autowired
private RedisTemplate redisTemplate;
//切入点,对登录方法不进行切入
@Pointcut("execution(* com.xiaomin.login_redis.controller.*.*(..))"
+ "&& !execution(* com.xiaomin.login_redis.controller.LoginController.*(..))" //登录方法
+"&& !execution(* com.xiaomin.login_redis.controller.UserinfoController.*(..))")//跳转登录页
public void loing(){
}
/**
* 前置增强,校验redis中用户的信息
*/
@Before("loing()")
public void before(){
//1、得到request对象
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//2、获取客户端保存的cookie
Cookie cookie = CookieUtil.getCookie(request, CookieConstant.TOKEN);
//3、判断cookie是否存在
if(cookie==null){
logger.warn("【登录校验】Cookie中查询不到token");
throw new AuthorizeException();
}
//4、从Redis中查询token是否存在
Object token = redisTemplate.opsForValue().get(String.format(RedisConstant.TOKEN,cookie.getValue()));
if(token==null){
logger.warn("【登录校验】Redis中查不到token");
throw new AuthorizeException();
}
System.out.println(token);
}
}
LogoutController.java
当用户主动退出系统的时候, 也要在server中删除redis的key
package com.xiaomin.login_redis.controller;
import com.xiaomin.login_redis.constant.CookieConstant;
import com.xiaomin.login_redis.constant.RedisConstant;
import com.xiaomin.login_redis.enums.ResultEnum;
import com.xiaomin.login_redis.exception.AuthorizeException;
import com.xiaomin.login_redis.pojo.vo.ResultVo;
import com.xiaomin.login_redis.utils.CookieUtil;
import com.xiaomin.login_redis.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
/**
* 退出系统
* @create 2020-04-08 13:44
*/
@RestController
public class LogoutController {
@Autowired
private RedisTemplate redisTemplate;
/**
* 退出系统方法,需要把redis中的key给删除,客户端的cookie没有设置存活时间,会话关闭,及结束。
* @param request
* @return
*/
@GetMapping("/logout")
public ResultVo logout(HttpServletRequest request){
Cookie cookie = CookieUtil.getCookie(request, CookieConstant.TOKEN);
if(cookie==null){
throw new AuthorizeException();
}
Boolean result = redisTemplate.delete(String.format(RedisConstant.TOKEN, cookie.getValue()));
if(result){
return ResultUtil.build(ResultEnum.LOGOUT,"");
}
throw new AuthorizeException();
}
}
测试截图:
源代码下载:
链接:https://pan.baidu.com/s/1WwerlIn0n-vUpq_MbUGNNA
提取码:3o52
复制这段内容后打开百度网盘手机App,操作更方便哦