课堂笔记20230816

亮子 2023-08-16 03:59:31 10386 0 0 0

Mybatis Plus的逻辑删除

mybatis-plus:
  type-aliases-package: com.monte.pojo  #别名
  configuration:
    map-underscore-to-camel-case: true  #驼峰映射
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      id-type: uuid  #id生成策略  uuid随机生成id
      logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

图片alt

用户登录

  • 登录代码
    @Override
    public ResultVo login(UserLoginVo userLoginVo) {
        //--1 判断用户是否存在
        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(TbUser::getUserName, userLoginVo.getUserName()).last("limit 1");

        TbUser one = getOne(wrapper);
        if(one == null) {
            return ResultVo.FAILED(404, "用户不存在");
        }

        //--2 判断密码是否正确
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        boolean ok = encoder.matches(userLoginVo.getUserPass(), one.getUserPass());
        if(!ok) {
            return ResultVo.FAILED(403, "密码不正确");
        }

        //--3 生成token、并存储到redis中
        JwtBuilder builder = Jwts.builder();
        String token = builder.signWith(SignatureAlgorithm.HS256, "123456")
                .claim("userId", "" + one.getUserId())
                .claim("userName", one.getUserName())
                .compact();

        //--4 返回登录信息
        redisTemplate.opsForValue().set(token, token, 30, TimeUnit.MINUTES);

        TbUserVo tbUserVo = new TbUserVo();
        BeanUtils.copyProperties(one, tbUserVo);
        tbUserVo.setUserPass(null);
        tbUserVo.setToken(token);

        return ResultVo.SUCCESS(tbUserVo);
    }
  • 用户注册
    @Override
    public ResultVo add(TbUserVo tbUserVo) {
        //--1 判断用户是否存在
        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(TbUser::getUserName, tbUserVo.getUserName()).last("limit 1");

        TbUser one = getOne(wrapper);
        if(one != null) {
            return ResultVo.FAILED(405, "用户已存在");
        }

        //--2 复制用户信息
        TbUser tbUser = new TbUser();
        BeanUtils.copyProperties(tbUserVo,tbUser);

        //--3 加密密码
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String pwd = encoder.encode(tbUserVo.getUserPass());
        tbUser.setUserPass(pwd);

        return save(tbUser)?ResultVo.SUCCESS():ResultVo.FAILED(501,"用户添加错误");
    }

git clone xxxx

每次修改之前,需要执行下面步骤:
1、git commit -m ""
2、git pull

浏览器存储token,并且关闭浏览器要删除token

                    userLogin(this.loginForm).then(res => {
                        console.log('userLogin', res)
                        if(res.data.code == 200) {
                            let user = res.data.data
                            console.log('user', user)
                            // 浏览器(不是页面)关闭,数据就会被删除,最好存储为字符串
                            window.sessionStorage.setItem('user', JSON.stringify(user));
                            window.sessionStorage.setItem('token', user.token);
                            // 浏览器关闭,也不会删除;卸载浏览器,在安装浏览器;通过浏览器手动删除
                            //window.localStorage
                        }
                    })

图片alt

  • 验证码登录
    @Override
    public ResultVo smsLogin(MobileVo mobileVo) {
        //--1 验证验证吗是否正确
        String key = mobileVo.getMobile() + mobileVo.getCode();
        Boolean hasKey = redisTemplate.hasKey(key);
        if(!hasKey) {
            return ResultVo.FAILED(404, "验证码已过期");
        }

        //--2 获取用户信息
        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(TbUser::getUserMobile, mobileVo.getMobile()).last("limit 1");

        TbUser one = this.getOne(wrapper);
        if(one == null) {
            return ResultVo.FAILED(404, "用户不存在");
        }

        //--3 生成token并存入redis
        JwtBuilder builder = Jwts.builder();
        String token = builder.signWith(SignatureAlgorithm.HS256, "123456")
                .claim("userId", "" + one.getUserId())
                .claim("userName", one.getUserName())
                .compact();
        redisTemplate.opsForValue().set(token, token, 30, TimeUnit.MINUTES);

        //--4 返回用户信息
        TbUserVo tbUserVo = new TbUserVo();
        BeanUtils.copyProperties(one, tbUserVo);
        tbUserVo.setUserPass(null);
        tbUserVo.setToken(token);

        return ResultVo.SUCCESS(tbUserVo);
    }

同一账号连续三次密码错误锁定5分钟禁止登陆

1、在redis中存储一个数据,只要密码错误一次就累计1次,达到5次,后端将不允许登录,设置过期 时间5分钟

    @Override
    public ResultVo login(UserLoginVo userLoginVo) {
        //--1 判断用户是否存在
        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(TbUser::getUserName, userLoginVo.getUserName()).last("limit 1");

        TbUser one = getOne(wrapper);
        if(one == null) {
            return ResultVo.FAILED(404, "用户不存在");
        }

        // 判断用户是否锁定状态,如果是锁定状态,则直接返回
        String loginKey = ""+one.getUserId()+":ERROR";
        if(redisTemplate.hasKey(loginKey)) {
            return ResultVo.FAILED(403, "登录错误次数超过3次被锁定5分钟");
        }

        //--2 判断密码是否正确
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        boolean ok = encoder.matches(userLoginVo.getUserPass(), one.getUserPass());
        if(!ok) {
            // 同一账号连续三次密码错误锁定5分钟禁止登陆
            String key = ""+one.getUserId()+":TRY";
            Long increment = redisTemplate.opsForValue().increment(key);
            if(increment >= 3) {

                redisTemplate.opsForValue().set(loginKey, "", 5, TimeUnit.MINUTES);
                redisTemplate.opsForValue().set(key, 0);
            }

            return ResultVo.FAILED(403, "密码不正确");
        }

        //--3 生成token、并存储到redis中
        JwtBuilder builder = Jwts.builder();
        String token = builder.signWith(SignatureAlgorithm.HS256, "123456")
                .claim("userId", "" + one.getUserId())
                .claim("userName", one.getUserName())
                .compact();

        //--4 返回登录信息
        redisTemplate.opsForValue().set(token, token, 30, TimeUnit.MINUTES);

        TbUserVo tbUserVo = new TbUserVo();
        BeanUtils.copyProperties(one, tbUserVo);
        tbUserVo.setUserPass(null);
        tbUserVo.setToken(token);

        return ResultVo.SUCCESS(tbUserVo);
    }

将token保存到Redis,有效期2分钟,在网关中判断2分钟内有操作则自动续期

package com.bw2102a.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author 军哥
 * @version 1.0
 * @description: GateWayFilter
 * @date 2023/8/14 11:35
 */

@Configuration
@Slf4j
public class GateWayFilter implements GlobalFilter, Ordered {

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        // 获取请求和返回信息
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        // 白名单
        log.info("url="+request.getURI());
        if(request.getURI().toString().contains("/user/login")
                || request.getURI().toString().contains("/user/sendSms")
                || request.getURI().toString().contains("/user/smsLogin")) {
            return chain.filter(exchange);
        }

        // 检查token
        // 没有带token
        String token = request.getHeaders().getFirst("token");
        if(token == null) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        // token过期了
        if(!redisTemplate.hasKey(token)) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

        // token续期
        redisTemplate.expire(token, 2, TimeUnit.MINUTES);

        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}