先讲一下登录验证的过程:
1.客户端请求登录,输入必要的信息
2.服务器验证信息,通过后返回一个token 保存在cookie 中,并且把cookie 保存在redis里面,用来保存用户
3.每次请求页面,带上cookie,
4.客户端验证cookie,并且查验redis token 的正确性,如果正确,就是用户已登录的状态,可以返回请求的页面
实现过程:
登录-》验证-》生成token,返回cookie,保存cookie到redis-》每次验证cookie-》验证成功,返回页面
代码实现:
由于用到redis,需要添加maven依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
新建Controller 包含验证登录和注销登录两个方法:
@Controller
@RequestMapping("/seller")
@Slf4j
public class SellerLoginController {
@Autowired
private SellerService sellerService;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private ProjectUrlConfig projectUrlConfig;
@RequestMapping("/login")
public ModelAndView login(@RequestParam("openid") String openid,
HttpServletResponse response,
Map<String,Object> map)
{
//根据openid 查询是否存在
SellerInfo sellerInfo = sellerService.findSellerInfo(openid);
if(sellerInfo == null)
{
log.error("【微信扫码登录失败】用户未找到 ");
throw new ResultException(ResultEnum.LOGIN_ERROR);
}
//找到后就保存到redis
//生成token,有很多种方法,你可以根据根据实际情况选择,这里只是简单生成一个uuid
String token = UUID.randomUUID().toString();
//设置超时时间
Integer expire = RedisContant.EXPIRE;
redisTemplate.opsForValue().set(String.format(RedisContant.TOKEN_PREFIX, token), openid, expire, TimeUnit.SECONDS);
//保存到cookies
CookieUtil.set(response, CookieContant.TOKEN, token, expire);
return new ModelAndView("redirect:"+projectUrlConfig.getSell()+"/sell/seller/order/list");
}
@GetMapping("/logout")
public ModelAndView logout(HttpServletRequest request,
HttpServletResponse response,
Map<String ,Object> map)
{
//1.从cookie 里面查询 如果有
Cookie cookie = CookieUtil.get(request, CookieContant.TOKEN);
if(cookie!=null)
{
//2.删除cookie数据
CookieUtil.set(response, CookieContant.TOKEN, null, 0);
//3.删除redis的数据
redisTemplate.opsForValue().getOperations().delete(String.format(RedisContant.TOKEN_PREFIX, cookie.getValue()));
}
map.put("msg", ResultEnum.LOGOUT_SUCCESS);
map.put("url", projectUrlConfig.getSell()+"/sell/seller/order/list");
return new ModelAndView("common/success", map);
}
}
在这里包含了保存cookie 和获取cookie 的两个方法,在CookieUtil类中
扫描二维码关注公众号,回复:
8616515 查看本文章
public class CookieUtil {
/**
* 设置
* @param response
* @param name
* @param value
* @param maxAge
*/
public static void set(HttpServletResponse response,
String name,
String value,
int maxAge) {
Cookie cookie = new Cookie(name, value);
cookie.setPath("/");
cookie.setMaxAge(maxAge);
response.addCookie(cookie);
}
/**
* 返回cookie
* @param request
* @param name
* @return
*/
public static Cookie get(HttpServletRequest request,
String name)
{
Map<String,Cookie> cookieMap = cookies2map(request);
if(cookieMap!=null)
{
if(cookieMap.containsKey(name))
{
return cookieMap.get(name);
}
}
return null;
}
/**
* 将cookie 转换为 map
* @param request
* @return
*/
private static Map<String,Cookie> cookies2map(HttpServletRequest request)
{
Map<String,Cookie> map = new HashMap<>();
Cookie[] cookies = request.getCookies();
if (cookies!=null)
{
for(Cookie cookie:cookies)
{
map.put(cookie.getName(), cookie);
}
}
return map;
}
}
返回正确后,再每次请求的时候,我们都要验证一下cookie,我们可以把这个验证设置为一个切面,来进行验证
@Component
@Aspect
@Slf4j
public class SellAuthorizeAspect {
@Autowired
RedisTemplate redisTemplate;
//进行验证的切面
@Pointcut("execution(public * com.imooc.sell.controller.Seller*.*(..))")
public void verify(){}
@Before("verify()")
public void doVerify() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
//查询cookie
Cookie cookie = CookieUtil.get(request, CookieContant.TOKEN);
if(cookie == null)
{
log.error("【登录验证】错误,没有登录");
throw new SellAuthorizeException();
}
//查询radis
if (!redisTemplate.opsForValue().getOperations().hasKey(String.format(RedisContant.TOKEN_PREFIX, cookie))) {
log.error("【登录验证】错误,没有登录");
throw new SellAuthorizeException();
}
}
}
在验证的时候,我们这里抛出了异常,说明是没有登录的异常,对于没有登录,我们会转到登录页面处理,这里就有一个异常的处理过程
先新建一个没有登录的异常
@Getter
@Setter
@ToString
public class SellAuthorizeException extends RuntimeException {
}
然后捕获异常进行处理 我们上面抛出的是SellAuthorizeException
@ControllerAdvice
public class SellAuthorizeExceptionHandle {
@Autowired
ProjectUrlConfig projectUrlConfig;
@ExceptionHandler(value = SellAuthorizeException.class)
public ModelAndView authorizeExceptionHandle()
{
return new ModelAndView("redirect:"http://localhost:8080"+
"/sell/seller/login");
}
}
这样一个登录的验证就做好了