Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: check whether login from new place #127

Merged
merged 1 commit into from
Oct 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ public class EmailConstants {

public static final String ACTIVE_ACCOUNT_TITLE = "Active your account of ConnecTi";

public static final String NEW_LOGIN_TITLE = "Safety Notice: Login from new place";

}
93 changes: 93 additions & 0 deletions src/main/java/tech/crm/crmserver/common/utils/IpUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package tech.crm.crmserver.common.utils;


import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

import org.springframework.http.*;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import tech.crm.crmserver.dao.IpAddress;

/**
* ip util
*
* @author Lingxiao Li
* @since 2021-10-19
**/
public class IpUtil {

private final static String URL = "http://ip-api.com/json/";

/**
* get ip by httpServletRequest<br/>
* Keep a good mood
* from https://blog.csdn.net/qq_35387940/article/details/84391784
* CC 4.0 BY-SA<br/>
*
* @author JCccc
* @since 2018-11-23
**/
public static String getIpAddr(HttpServletRequest request) {
String ipAddress = null;
try {
ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (ipAddress.equals("127.0.0.1")) {
return null;
}
}
if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
// = 15
if (ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
} catch (Exception e) {
ipAddress="";
}
// ipAddress = this.getRequest().getRemoteAddr();

return ipAddress;
}




/**
* https://blog.csdn.net/zai_xia/article/details/80926157
* @author Seven.wk
* @since 2018/07/04
* @param ip ip address
*/
public static IpAddress sendPostRequest(String ip){

RestTemplate client = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
HttpMethod method = HttpMethod.POST;
String url = URL + ip;

headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(null, headers);

ResponseEntity<IpAddress> response = client.exchange(URL, method, requestEntity, IpAddress.class);
if(response.getStatusCode() != HttpStatus.OK){
return null;
}

return response.getBody();
}


}
42 changes: 34 additions & 8 deletions src/main/java/tech/crm/crmserver/controller/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
import tech.crm.crmserver.common.constants.SecurityConstants;
import tech.crm.crmserver.common.exception.BadPhotoException;
import tech.crm.crmserver.common.response.ResponseResult;
import tech.crm.crmserver.common.utils.IpUtil;
import tech.crm.crmserver.common.utils.NullAwareBeanUtilsBean;
import tech.crm.crmserver.dao.User;
import tech.crm.crmserver.dto.*;
import tech.crm.crmserver.service.IpAddressService;
import tech.crm.crmserver.service.TokenKeyService;
import tech.crm.crmserver.service.UserService;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;


Expand All @@ -36,16 +39,26 @@ public class UserController {
@Autowired
private UserService userService;

@Autowired
private IpAddressService ipAddressService;

/**
* The login API
*
* @param loginRequest the form for login
* @return return 200 when login successfully, return 400 and reason in the msg
*/
@PostMapping("/login")
public ResponseResult<Object> login(@Validated @RequestBody LoginRequest loginRequest){
public ResponseResult<Object> login(@Validated @RequestBody LoginRequest loginRequest,
HttpServletRequest httpServletRequest){
//login and return the token
String token = userService.login(loginRequest);
User user = userService.verify(loginRequest);
userService.dealPendingUser(user);
//check ip
String ip = IpUtil.getIpAddr(httpServletRequest);
ipAddressService.checkIpAddress(user.getId(), ip);
//return the token
String token = tokenKeyService.createToken(user);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set(SecurityConstants.TOKEN_HEADER, token);
return ResponseResult.suc("successfully login!","",httpHeaders);
Expand All @@ -70,10 +83,14 @@ public ResponseResult<Object> logout(@RequestHeader("Authorization") String toke
* @return 200 when successfully register and set Authorization in response header
*/
@PostMapping
public ResponseResult<Object> register(@Validated @RequestBody UserRegisterDTO userRegisterDTO){
public ResponseResult<Object> register(@Validated @RequestBody UserRegisterDTO userRegisterDTO,
HttpServletRequest httpServletRequest){
User user = userService.fromUserRegisterDTO(userRegisterDTO);
//check whether there is same email already exist
userService.register(user);
User register = userService.register(user);
//save ip
String ip = IpUtil.getIpAddr(httpServletRequest);
ipAddressService.saveNewIp(register.getId(),ip);
return ResponseResult.suc("successfully sign up!");
}

Expand Down Expand Up @@ -105,8 +122,13 @@ public ResponseResult<Object> getUser() {
* @return response with msg
*/
@PostMapping("/resetPassword")
public ResponseResult<Object> resetPassword(@Validated @RequestBody ResetPasswordDTO resetPasswordDTO){
userService.resetPassword(resetPasswordDTO.getEmail());
public ResponseResult<Object> resetPassword(@Validated @RequestBody ResetPasswordDTO resetPasswordDTO,
HttpServletRequest httpServletRequest){
User user = userService.resetPassword(resetPasswordDTO.getEmail());
//remove all ip and save new ip
String ip = IpUtil.getIpAddr(httpServletRequest);
ipAddressService.cleanIpByUserId(user.getId());
ipAddressService.saveNewIp(user.getId(),ip);
return ResponseResult.suc("Check your email for new password!");
}

Expand All @@ -123,8 +145,12 @@ public ResponseResult<Object> updateUserDetail(@Validated @RequestBody UserUpdat
}

@PostMapping("/verify")
public ResponseResult<Object> verifyEmail(){
userService.activePendingUser(userService.getId());
public ResponseResult<Object> verifyEmail(HttpServletRequest httpServletRequest){
Integer userId = userService.getId();
userService.activePendingUser(userId);
//check ip
String ip = IpUtil.getIpAddr(httpServletRequest);
ipAddressService.checkIpAddress(userId, ip);
return ResponseResult.suc("Successfully active user account");
}

Expand Down
39 changes: 39 additions & 0 deletions src/main/java/tech/crm/crmserver/dao/IpAddress.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package tech.crm.crmserver.dao;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* <p>
* entity
* </p>
*
* @author Lingxiao
* @since 2021-10-19
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
@TableName("ip_address")
public class IpAddress implements Serializable {

private static final long serialVersionUID = 1L;

private Integer userId;

private String country;

@TableField("region_name")
private String regionName;

private String city;


}
18 changes: 18 additions & 0 deletions src/main/java/tech/crm/crmserver/mapper/IpAddressMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package tech.crm.crmserver.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
import tech.crm.crmserver.dao.IpAddress;

/**
* <p>
* Mapper
* </p>
*
* @author Lingxiao
* @since 2021-10-19
*/
@Repository
public interface IpAddressMapper extends BaseMapper<IpAddress> {

}
39 changes: 39 additions & 0 deletions src/main/java/tech/crm/crmserver/service/IpAddressService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package tech.crm.crmserver.service;

import com.baomidou.mybatisplus.extension.service.IService;
import tech.crm.crmserver.dao.IpAddress;

/**
* <p>
* service
* </p>
*
* @author Lingxiao
* @since 2021-10-19
*/
public interface IpAddressService extends IService<IpAddress> {

/**
* check whether this ip is a new ip for the user<br/>
* if yes, send a email to user and return true
* if no, return false
* @param userId the id of user
* @param ip the ip
* @return whether is a new ip
*/
public boolean checkIpAddress(Integer userId, String ip);

/**
* save a new address according to ip
* @param userId the id of user
* @param ip the ip
*/
public void saveNewIp(Integer userId, String ip);

/**
* clean ip address by user id
* @param userId the id of user
*/
public void cleanIpByUserId(Integer userId);

}
4 changes: 3 additions & 1 deletion src/main/java/tech/crm/crmserver/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ public static Map<String, String> searchKey(String searchKey){
* then send the password to the email<br/>
* and delete all the token of this user in database
* @param email the email of user who needs reset password
* @return user who reset password
*/
public void resetPassword(String email);
public User resetPassword(String email);

/**
* update the recent activity time of user
Expand Down Expand Up @@ -144,4 +145,5 @@ public static Map<String, String> searchKey(String searchKey){
* @param originalPhoto binary photo
*/
public void updatePhoto(Integer userId, MultipartFile originalPhoto) throws IOException;

}
Loading