使用单例模式,工厂模式,实现多种方法登录校验(账号密码登录,手机号验证码登录)



前言

借鉴使用单例模式,工厂模式,实现多种审批(购买审批,订单审批…)


一、LoginFactory类(使用两种常见的设计模式)

@Component
public class LoginFactory {
    private static Map<String, LoginStrategy> operationMap = new HashMap<>();


    @Autowired
    public LoginFactory(List<LoginStrategy> loginStrategies) {
        for (LoginStrategy loginStrategy : loginStrategies) {
            operationMap.put(loginStrategy.type(), loginStrategy);
        }
    }

    /**
     * 获取对应的目标实现类
     *
     * @param loginType
     * @return
     */
    public LoginStrategy getOperation(String loginType) {
        LoginStrategy loginStrategy = operationMap.get(loginType);
        Optional.ofNullable(loginStrategy).orElseThrow(() -> new BizException("不支持的登录方式"));
        return loginStrategy;
    }
}

二、通用校验接口LoginStrategy

public interface LoginStrategy {

    String type();

    UserVO login(LoginDTO loginDTO);
}

二、通用审批接口实现类


/**
 * @description 用户名密码登录
 */
@Component
public class NameLoginStrategy implements LoginStrategy {

    @Resource
    private UserService userService;

    @Resource
    private RedisUtil redisUtil;


    @Override
    public UserVO login(LoginDTO loginDTO) {
        UserVO userVO = userService.selectOneByMap(loginDTO.getLoginName());
        Optional.ofNullable(userVO).orElseThrow(() -> new BizException("用户名或密码错误"));
        //解密
        String fromInput = RsaUtil.decode(loginDTO.getPassword());
        String fromDb = RsaUtil.decode(userVO.getPassword());
        if (!StrUtil.equals(fromInput, fromDb)) {
            throw new BizException("用户名或密码输入错误!");
        }
        if (ObjectUtil.equals(userVO.getIsFreeze(), 1)) {
            throw new BizException("当前账号已被冻结!");
        }
        //使用satoken权限校验框架
        StpUtil.login(userVO.getCode());
        String token = StpUtil.getTokenValue();
        userVO.setToken(token);
        redisUtil.set(token, JSONUtil.toJsonStr(userVO), 86400);
        return userVO;
    }

    @Override
    public String type() {
        return "nameLogin";
    }
}
/**
 * @description 手机号验证码登录
 */
@Component
public class PhoneLoginStrategy implements LoginStrategy {


    @Resource
    private UserService userService;

    @Resource
    private RedisUtil redisUtil;


    @Override
    public UserVO login(LoginDTO loginDTO) {
        UserVO userVO = portalUserService.selectOneByMap(loginDTO.getPhone());
        Optional.ofNullable(portalUserVO).orElseThrow(() -> new BizException("该手机号未被注册"));
        if (ObjectUtil.equals(portalUserVO.getIsFreeze(), 1)) {
            throw new BizException("该手机号对应的账号已被冻结!");
        }
        //TODO 手机验证码验证

        //使用satoken权限校验框架
        StpUtil.login(userVO.getCode());
        String token = StpUtil.getTokenValue();
        userVO.setToken(token);
        redisUtil.set(token, JSONUtil.toJsonStr(userVO), 86400);
        return userVO;
    }

    @Override
    public String type() {
        return "phoneLogin";
    }


}

三、Controller

  @Resource
    private LoginFactory loginFactory;
    
    /**
     * 电话号码登录
     *
     * @param loginDto
     * @return
     */
    @PostMapping("/login")
    public UserVo login(@RequestBody LoginDTO loginDto) {
        return loginFactory.getLogin("phoneLogin").login(loginDto);
    }

    /**
     * 账号密码登录
     *
     * @param loginDto
     * @return
     */
    @PostMapping("/login")
    public UserVo login(@RequestBody LoginDTO loginDto) {
        return loginFactory.getLogin("nameLogin").login(loginDto);
    }

更多推荐