diff --git a/unilife-server/pom.xml b/unilife-server/pom.xml index b970ace..b10e4b3 100644 --- a/unilife-server/pom.xml +++ b/unilife-server/pom.xml @@ -32,8 +32,16 @@ org.projectlombok lombok + 1.18.36 true + + + org.lionsoul + ip2region + 2.7.0 + + org.springframework.boot spring-boot-starter-test diff --git a/unilife-server/src/main/java/com/unilife/controller/UserController.java b/unilife-server/src/main/java/com/unilife/controller/UserController.java index 61ecf94..8e6bd5f 100644 --- a/unilife-server/src/main/java/com/unilife/controller/UserController.java +++ b/unilife-server/src/main/java/com/unilife/controller/UserController.java @@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import javax.servlet.http.HttpServletRequest; import java.time.Duration; @@ -38,14 +39,14 @@ public class UserController { @ApiOperation(value = "用户注册") @PostMapping("register") - public Result register(@RequestBody RegisterDTO registerDTO) { - return userService.register(registerDTO); + public Result register(@RequestBody RegisterDTO registerDTO, HttpServletRequest request) { + return userService.register(registerDTO,request); } @ApiOperation(value = "用户登录") @PostMapping("login") - public Result login(@RequestBody LoginDTO loginDTO) { - Result login = userService.login(loginDTO); + public Result login(@RequestBody LoginDTO loginDTO,HttpServletRequest request) { + Result login = userService.login(loginDTO,request); //登陆成功后生成jwt令牌 LoginVO vo=(LoginVO) login.getData(); if (vo == null) { @@ -62,16 +63,16 @@ public class UserController { @ApiOperation(value = "获取邮箱验证码") @PostMapping("code") - public Result getCode(@RequestBody EmailDTO emailDto){ + public Result getCode(@RequestBody EmailDTO emailDto,HttpServletRequest request) { String email=emailDto.getEmail(); log.debug("收到的原始邮箱: {}", email); - return userService.sendVerificationCode(email); + return userService.sendVerificationCode(email,request); } @ApiOperation(value = "邮箱验证码登录") @PostMapping("login/code") - public Result loginWithEmailCode(@RequestBody LoginEmailDTO loginEmailDTO){ - return userService.loginWithEmail(loginEmailDTO); + public Result loginWithEmailCode(@RequestBody LoginEmailDTO loginEmailDTO,HttpServletRequest request) { + return userService.loginWithEmail(loginEmailDTO,request); } } diff --git a/unilife-server/src/main/java/com/unilife/mapper/UserMapper.java b/unilife-server/src/main/java/com/unilife/mapper/UserMapper.java index 9520351..a5020f4 100644 --- a/unilife-server/src/main/java/com/unilife/mapper/UserMapper.java +++ b/unilife-server/src/main/java/com/unilife/mapper/UserMapper.java @@ -9,4 +9,6 @@ public interface UserMapper { void insert(User user); User FindByEmail(@Param("email") String email, @Param("password") String password); User getUserByEmail(String email); + void UpdateIPLocation(@Param("email") String email,@Param("loginIp") String loginIp); + User FindByOnlyEmail(@Param("email") String email); } diff --git a/unilife-server/src/main/java/com/unilife/model/vo/LoginVO.java b/unilife-server/src/main/java/com/unilife/model/vo/LoginVO.java index e2d0470..fbb63d9 100644 --- a/unilife-server/src/main/java/com/unilife/model/vo/LoginVO.java +++ b/unilife-server/src/main/java/com/unilife/model/vo/LoginVO.java @@ -16,6 +16,6 @@ public class LoginVO { private Byte isVerified; private Byte status; private String token; - + private String LoginIp; } diff --git a/unilife-server/src/main/java/com/unilife/model/vo/RegisterVO.java b/unilife-server/src/main/java/com/unilife/model/vo/RegisterVO.java index 2ea5a26..dfc60ad 100644 --- a/unilife-server/src/main/java/com/unilife/model/vo/RegisterVO.java +++ b/unilife-server/src/main/java/com/unilife/model/vo/RegisterVO.java @@ -11,5 +11,5 @@ public class RegisterVO { private Long id; private String username; private String nickname; - + private String loginIp; } diff --git a/unilife-server/src/main/java/com/unilife/service/IPLocationService.java b/unilife-server/src/main/java/com/unilife/service/IPLocationService.java new file mode 100644 index 0000000..bed401e --- /dev/null +++ b/unilife-server/src/main/java/com/unilife/service/IPLocationService.java @@ -0,0 +1,9 @@ +package com.unilife.service; +import com.unilife.model.dto.LoginDTO; + +import javax.servlet.http.HttpServletRequest; + +public interface IPLocationService { + public String getIPLocation(String ip); + public String getClientIP(HttpServletRequest request); +} diff --git a/unilife-server/src/main/java/com/unilife/service/UserService.java b/unilife-server/src/main/java/com/unilife/service/UserService.java index 5cc3fc4..6752f6f 100644 --- a/unilife-server/src/main/java/com/unilife/service/UserService.java +++ b/unilife-server/src/main/java/com/unilife/service/UserService.java @@ -5,12 +5,15 @@ import com.unilife.model.dto.LoginDTO; import com.unilife.model.dto.LoginEmailDTO; import com.unilife.model.dto.RegisterDTO; +import javax.servlet.http.HttpServletRequest; + public interface UserService { - Result register(RegisterDTO registerDTO); - Result login(LoginDTO loginDTO); + Result register(RegisterDTO registerDTO, HttpServletRequest request); + + Result login(LoginDTO loginDTO,HttpServletRequest request); - Result sendVerificationCode(String email); + Result sendVerificationCode(String email,HttpServletRequest request); - Result loginWithEmail(LoginEmailDTO loginEmailDTO); + Result loginWithEmail(LoginEmailDTO loginEmailDTO,HttpServletRequest request); } diff --git a/unilife-server/src/main/java/com/unilife/service/impl/IPLocationServicelmpl.java b/unilife-server/src/main/java/com/unilife/service/impl/IPLocationServicelmpl.java new file mode 100644 index 0000000..3f1377f --- /dev/null +++ b/unilife-server/src/main/java/com/unilife/service/impl/IPLocationServicelmpl.java @@ -0,0 +1,77 @@ +package com.unilife.service.impl; + + +import com.unilife.service.IPLocationService; +import org.lionsoul.ip2region.xdb.Searcher; +import org.springframework.stereotype.Service; +import org.springframework.util.ReflectionUtils; +import org.springframework.util.ResourceUtils; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.IOException; +import java.io.FileNotFoundException; + +@Service +public class IPLocationServicelmpl implements IPLocationService { + + private Searcher searcher; + + @Override + public String getIPLocation(String ip) { + if("127.0.0.1".equals(ip) || ip.startsWith("192.168")){ + return "局域网 IP"; + } + if(searcher == null){ + try{ + File file = ResourceUtils.getFile("classpath:ipdb/ip2region.xdb"); + String dbPath = file.getPath(); + //System.out.println(dbPath); + searcher = Searcher.newWithFileOnly(dbPath); + } + catch(FileNotFoundException e){ + e.printStackTrace(); + return "IP地址库文件未找到"; + } + catch (IOException e){ + e.printStackTrace(); + return "IP地址库初始化失败"; + } + } + String region = null; + String errormessage = null; + try{ + region = searcher.search(ip); + } + catch (Exception e){ + errormessage = e.getMessage(); + if(errormessage != null && errormessage.length() > 256){ + errormessage = errormessage.substring(0, 256); + } + e.printStackTrace(); + return "IP归属地查找失败!" + errormessage; + } + return (region == null) ? "未知归属地" : region; + } + + @Override + public String getClientIP(HttpServletRequest request) { + if("127.0.0.1".equals(request.getRemoteAddr())){ + return "14.21.80.0"; + }//实际开发的时候删掉! + String ip = request.getHeader("X-forwarded-for"); + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + return (ip != null) ? ip.split(",")[0] : null; + } +} diff --git a/unilife-server/src/main/java/com/unilife/service/impl/UserServiceImpl.java b/unilife-server/src/main/java/com/unilife/service/impl/UserServiceImpl.java index 9b0cd6f..6df5ada 100644 --- a/unilife-server/src/main/java/com/unilife/service/impl/UserServiceImpl.java +++ b/unilife-server/src/main/java/com/unilife/service/impl/UserServiceImpl.java @@ -11,6 +11,7 @@ import com.unilife.model.dto.RegisterDTO; import com.unilife.model.entity.User; import com.unilife.model.vo.LoginVO; import com.unilife.model.vo.RegisterVO; +import com.unilife.service.IPLocationService; import com.unilife.service.UserService; import com.unilife.utils.JwtUtil; import com.unilife.utils.RegexUtils; @@ -25,6 +26,7 @@ import org.springframework.stereotype.Service; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; +import javax.servlet.http.HttpServletRequest; import java.time.Duration; import java.util.HashMap; @@ -37,6 +39,9 @@ import static com.unilife.common.constant.RedisConstant.LOGIN_EMAIL_KEY; @Service public class UserServiceImpl implements UserService { + @Autowired + private IPLocationService ipLocationService; + @Autowired private UserMapper userMapper; @@ -56,19 +61,30 @@ public class UserServiceImpl implements UserService { @Override - public Result register(RegisterDTO registerDTO) { + public Result register(RegisterDTO registerDTO, HttpServletRequest request) { if(registerDTO.getEmail().isEmpty() || registerDTO.getPassword().isEmpty()) { return Result.error(400,"邮箱或密码不能为空"); } + if(registerDTO.getPassword().length() < 6) { + return Result.error(400,"密码长度过短!"); + } + User getuser = userMapper.FindByOnlyEmail(registerDTO.getEmail()); + if(getuser != null) { + return Result.error(400,"用户已存在!"); + } User user = new User(); BeanUtil.copyProperties(registerDTO,user); + String IPAddress = ipLocationService.getClientIP(request); + String Location = ipLocationService.getIPLocation(IPAddress); + user.setLoginIp(Location); userMapper.insert(user); - RegisterVO registerVO = new RegisterVO(user.getId(),user.getUsername(),user.getNickname()); + RegisterVO registerVO = new RegisterVO(user.getId(),user.getUsername() + ,user.getNickname(),user.getLoginIp()); return Result.success(registerVO); } @Override - public Result login(LoginDTO loginDTO) { + public Result login(LoginDTO loginDTO,HttpServletRequest request) { User user = new User(); BeanUtil.copyProperties(loginDTO,user);//将登录的前端传来的消息拷贝给这个user User getuser = userMapper.FindByEmail(user.getEmail(),user.getPassword()); @@ -80,13 +96,17 @@ public class UserServiceImpl implements UserService { { return Result.error(loginDTO,"密码错误,登录失败!"); } - LoginVO loginVO=new LoginVO(); - BeanUtil.copyProperties(getuser,loginVO); - return Result.success(loginVO); + String LastLogIpLocation = getuser.getLoginIp(); + String IPAddress = ipLocationService.getClientIP(request); + String Location = ipLocationService.getIPLocation(IPAddress); + getuser.setLoginIp(Location); + userMapper.UpdateIPLocation(getuser.getEmail(), getuser.getLoginIp()); + LoginVO loginVO = new LoginVO(); + return Result.success(loginVO,"上次登录IP归属地为" + LastLogIpLocation); } @Override - public Result sendVerificationCode(String email) { + public Result sendVerificationCode(String email,HttpServletRequest request) { //1.校验邮箱是否合法 boolean emailInvalid = RegexUtils.isEmailInvalid(email); if(emailInvalid){ @@ -121,9 +141,11 @@ public class UserServiceImpl implements UserService { helper.setTo(email); helper.setSubject("UniLife - 登录验证码"); + String IPAddress = ipLocationService.getClientIP(request); + String Location = ipLocationService.getIPLocation(IPAddress); String content = "
" + "

您好!

" + - "

感谢您使用UniLife平台。您的验证码是:

" + + "

感谢您使用UniLife平台,本次登录地为" + Location + "您的验证码是:

" + "
" + code + "
" + @@ -150,7 +172,7 @@ public class UserServiceImpl implements UserService { } @Override - public Result loginWithEmail(LoginEmailDTO loginEmailDTO) { + public Result loginWithEmail(LoginEmailDTO loginEmailDTO,HttpServletRequest request) { String email=loginEmailDTO.getEmail(); if(RegexUtils.isEmailInvalid(email)){ @@ -174,17 +196,17 @@ public class UserServiceImpl implements UserService { // 5. 查询用户是否存在 User user=userMapper.getUserByEmail(email); if(user == null){ - user=createUserWithEmail(email); + user = createUserWithEmail(email,request); } //6.生成登录凭证 - String token=jwtUtil.generateToken(user.getId()); + //TODO + String token = jwtUtil.generateToken(user.getId()); // 8. 返回用户信息和登录凭证 Map userInfo = new HashMap<>(); - //HashMap userInfo.put("token", token); - userInfo.put("user", user); userInfo.put("token", token); + userInfo.put("user", user); return Result.success(userInfo); } @@ -192,14 +214,16 @@ public class UserServiceImpl implements UserService { /** * 使用邮箱信息创建新用户 */ - private User createUserWithEmail(String email) { + private User createUserWithEmail(String email,HttpServletRequest request) { User user = new User(); user.setEmail(email); user.setNickname("用户" + RandomUtil.randomString(6)); // 生成随机昵称 String username = email.split("@")[0]+"_"+ RandomUtil.randomString(4); // 使用@前面的部分作为用户名 user.setUsername(username); - String password=RandomUtil.randomString(6); + String password = RandomUtil.randomString(6); + String IPAddress = ipLocationService.getClientIP(request); + String Location = ipLocationService.getIPLocation(IPAddress); user.setPassword(password); user.setRole((byte)0); // 普通用户角色 @@ -207,7 +231,7 @@ public class UserServiceImpl implements UserService { user.setIsVerified((byte)0); // 未验证 user.setPoints(0); // 初始积分 user.setGender((byte)0); - + user.setLoginIp(Location);//注册地IP // 保存用户 try { userMapper.insert(user); diff --git a/unilife-server/src/main/resources/application.yml b/unilife-server/src/main/resources/application.yml index c803148..a4cc4fe 100644 --- a/unilife-server/src/main/resources/application.yml +++ b/unilife-server/src/main/resources/application.yml @@ -1,10 +1,10 @@ server: - port: 8080 + port: 8087 spring: datasource: url: jdbc:mysql://localhost:3306/UniLife?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8 username: root - password: 123456 + password: zhong20050428 driver-class-name: com.mysql.cj.jdbc.Driver mail: host: smtp.163.com diff --git a/unilife-server/src/main/resources/ipdb/ip2region.xdb b/unilife-server/src/main/resources/ipdb/ip2region.xdb new file mode 100644 index 0000000..7052c05 Binary files /dev/null and b/unilife-server/src/main/resources/ipdb/ip2region.xdb differ diff --git a/unilife-server/src/main/resources/mappers/UserMapper.xml b/unilife-server/src/main/resources/mappers/UserMapper.xml index e422367..2caed2f 100644 --- a/unilife-server/src/main/resources/mappers/UserMapper.xml +++ b/unilife-server/src/main/resources/mappers/UserMapper.xml @@ -11,6 +11,7 @@ + INSERT INTO users ( @@ -37,11 +38,23 @@ + + + + UPDATE users + SET login_ip = #{loginIp} + WHERE email = #{email} + +