springboot前后端分离,实现登录

思路:使用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,操作更方便哦

  • 4
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值