添加了显示IP归属地的功能

pull/2/head
zhong-hongye12355 2 months ago
parent 3adff4bbe0
commit d6b42b25d3

@ -32,8 +32,16 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

@ -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);
}
}

@ -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);
}

@ -16,6 +16,6 @@ public class LoginVO {
private Byte isVerified;
private Byte status;
private String token;
private String LoginIp;
}

@ -11,5 +11,5 @@ public class RegisterVO {
private Long id;
private String username;
private String nickname;
private String loginIp;
}

@ -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);
}

@ -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);
}

@ -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;
}
}

@ -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 = "<div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #eee; border-radius: 5px;\">" +
"<h2 style=\"color: #333;\">您好!</h2>" +
"<p>感谢您使用UniLife平台您的验证码是:</p>" +
"<p>感谢您使用UniLife平台,本次登录地为" + Location + "您的验证码是:</p>" +
"<div style=\"background-color: #f5f5f5; padding: 10px; text-align: center; font-size: 24px; font-weight: bold; letter-spacing: 5px; margin: 20px 0;\">" +
code +
"</div>" +
@ -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<String, Object> 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);

@ -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

@ -11,6 +11,7 @@
<result column="role" property="role"/>
<result column="is_verified" property="isVerified"/>
<result column="status" property="status"/>
<result column="login_ip" property="loginIp"/>
</resultMap>
<insert id="insert" parameterType="com.unilife.model.entity.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users (
@ -37,11 +38,23 @@
</insert>
<select id="FindByEmail" resultMap="userResultMap">
SELECT id, email, password, username, nickname, avatar, role, is_verified, status
SELECT id, email, password, username, nickname, avatar, role, is_verified, status,login_ip
FROM users
WHERE email = #{email} AND password = #{password}
</select>
<select id="FindByOnlyEmail" resultMap="userResultMap">
SELECT id, email, password, username, nickname, avatar, role, is_verified, status,login_ip
FROM users
WHERE email = #{email}
</select>
<update id="UpdateIPLocation" parameterType="com.unilife.model.entity.User">
UPDATE users
SET login_ip = #{loginIp}
WHERE email = #{email}
</update>
<select id="getUserByEmail" resultType="com.unilife.model.entity.User">
select username,
email,

Loading…
Cancel
Save