diff --git a/src/main/java/kr/co/hconnect/common/ApiResponseCode.java b/src/main/java/kr/co/hconnect/common/ApiResponseCode.java
index 2d26bc7..cbaf076 100644
--- a/src/main/java/kr/co/hconnect/common/ApiResponseCode.java
+++ b/src/main/java/kr/co/hconnect/common/ApiResponseCode.java
@@ -29,6 +29,10 @@ public enum ApiResponseCode {
* 격리상태 내역이 존재하지 않는 경우
*/
NOT_FOUND_QUARANTINE_INFO("14"),
+ /**
+ * 사용자 정보가 존재하지 않는 경우
+ */
+ NOT_FOUND_USER_INFO("15"),
/**
* 내원중인 격리/입소내역이 존재하지 않는 경우
diff --git a/src/main/java/kr/co/hconnect/controller/LoginController.java b/src/main/java/kr/co/hconnect/controller/LoginController.java
index 9a4a03b..234226e 100644
--- a/src/main/java/kr/co/hconnect/controller/LoginController.java
+++ b/src/main/java/kr/co/hconnect/controller/LoginController.java
@@ -1,8 +1,6 @@
package kr.co.hconnect.controller;
import kr.co.hconnect.service.UserService;
-import kr.co.hconnect.vo.LoginVO;
-import kr.co.hconnect.vo.SessionVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -14,6 +12,7 @@
/**
* 로그인 컨트롤러
*/
+@Deprecated
@Controller
@RequestMapping("/login")
public class LoginController {
@@ -48,20 +47,21 @@ public ModelAndView checkLogin(@RequestParam(value = "userId") String userId
, @RequestParam(value = "password") String password
, HttpServletRequest request) {
- // 로그인 정보 조회
- LoginVO loginVO = service.selectLoginInfo(userId, password);
-
- // 로그인 사용자 정보 세션에 설정
- if (loginVO.getUserVO() != null) {
- SessionVO sessionVO = new SessionVO();
- sessionVO.setUserId(loginVO.getUserVO().getUserId());
- sessionVO.setUserNm(loginVO.getUserVO().getUserNm());
- sessionVO.setCenterId(loginVO.getUserVO().getCenterId());
- request.getSession().setAttribute("sessionVO", sessionVO);
- }
-
+// // 로그인 정보 조회
+// LoginVO loginVO = service.selectLoginInfo(userId, password);
+//
+// // 로그인 사용자 정보 세션에 설정
+// if (loginVO.getUserVO() != null) {
+// SessionVO sessionVO = new SessionVO();
+// sessionVO.setUserId(loginVO.getUserVO().getUserId());
+// sessionVO.setUserNm(loginVO.getUserVO().getUserNm());
+// sessionVO.setCenterId(loginVO.getUserVO().getCenterId());
+// request.getSession().setAttribute("sessionVO", sessionVO);
+// }
+//
ModelAndView mv = new ModelAndView("jsonView");
- mv.addObject("loginFailMessage", loginVO.getFailMessage()); // 로그인 실패 사유
+// mv.addObject("loginFailMessage", loginVO.getFailMessage()); // 로그인 실패 사유
+ mv.addObject("loginFailMessage", ""); // 로그인 실패 사유
return mv;
}
diff --git a/src/main/java/kr/co/hconnect/domain/UserLoginInfo.java b/src/main/java/kr/co/hconnect/domain/UserLoginInfo.java
new file mode 100644
index 0000000..3e40749
--- /dev/null
+++ b/src/main/java/kr/co/hconnect/domain/UserLoginInfo.java
@@ -0,0 +1,42 @@
+package kr.co.hconnect.domain;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+
+/**
+ * 사용자 로그인 정보
+ */
+@Getter
+@Setter
+@NoArgsConstructor
+@ToString
+public class UserLoginInfo implements Serializable {
+
+ private static final long serialVersionUID = -1773620410222057699L;
+
+ /**
+ * 아이디
+ */
+ @NotNull(message = "{validation.null.loginId}")
+ private String loginId;
+
+ /**
+ * 비밀번호
+ */
+ @NotNull(message = "{validation.null.password}")
+ @Size(max = 20, message = "{validation.size.password}")
+ private String password;
+
+ /**
+ * 로그인 유지 여부
+ */
+ @Pattern(regexp = "^[YN]$")
+ private String rememberYn;
+}
diff --git a/src/main/java/kr/co/hconnect/domain/UserLoginResponse.java b/src/main/java/kr/co/hconnect/domain/UserLoginResponse.java
new file mode 100644
index 0000000..8596f47
--- /dev/null
+++ b/src/main/java/kr/co/hconnect/domain/UserLoginResponse.java
@@ -0,0 +1,23 @@
+package kr.co.hconnect.domain;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * 로그인 응답 정보
+ */
+@Getter
+@Setter
+@NoArgsConstructor
+@ToString
+public class UserLoginResponse extends BaseResponse {
+
+ private static final long serialVersionUID = -2461380484928982120L;
+
+ /**
+ * AccessToken
+ */
+ private String token;
+}
diff --git a/src/main/java/kr/co/hconnect/exception/NotFoundUserInfoException.java b/src/main/java/kr/co/hconnect/exception/NotFoundUserInfoException.java
new file mode 100644
index 0000000..e33150d
--- /dev/null
+++ b/src/main/java/kr/co/hconnect/exception/NotFoundUserInfoException.java
@@ -0,0 +1,23 @@
+package kr.co.hconnect.exception;
+
+/**
+ * 사용자 정보 미존재 Exception
+ */
+public class NotFoundUserInfoException extends RuntimeException {
+
+ private static final long serialVersionUID = 2009383189724700722L;
+
+ /**
+ * 오류 내역
+ */
+ private final String errorMessage;
+
+ public NotFoundUserInfoException(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ @Override
+ public String getMessage() {
+ return errorMessage;
+ }
+}
diff --git a/src/main/java/kr/co/hconnect/jwt/TokenProvider.java b/src/main/java/kr/co/hconnect/jwt/TokenProvider.java
index 1ea63e7..4c642e8 100644
--- a/src/main/java/kr/co/hconnect/jwt/TokenProvider.java
+++ b/src/main/java/kr/co/hconnect/jwt/TokenProvider.java
@@ -2,6 +2,7 @@
import io.jsonwebtoken.*;
import kr.co.hconnect.common.TokenStatus;
+import kr.co.hconnect.vo.UserVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,9 +61,32 @@ public String createToken() {
.setIssuedAt(now) // 발급시간
.setExpiration(validityInterval) // 만료시간
.signWith(key, keyAlg) // 키정보 및 해싱 알고리즘 정보
+ .claim("tokenType", "app")
.compact();
}
+ /**
+ * web 사용자 토큰 생성
+ *
+ * @return 토큰 정보
+ */
+ public String createUserToken(UserVO userVO) {
+ Date now = new Date();
+ // 토큰 만료시간
+ Date validityInterval = new Date(now.getTime() + this.validity);
+
+ return Jwts.builder()
+ .setHeaderParam(Header.TYPE, Header.JWT_TYPE) // 헤더 타입 지정
+ .setIssuer("HealthConnect") // 발급자 정보
+ .setIssuedAt(now) // 발급시간
+ .setExpiration(validityInterval) // 만료시간
+ .signWith(key, keyAlg) // 키정보 및 해싱 알고리즘 정보
+ .claim("tokenType", "web")
+ .claim("userId", userVO.getUserId())
+ .claim("userNm", userVO.getUserNm())
+ .compact();
+ }
+
/**
* 토큰 유효성 확인
*
diff --git a/src/main/java/kr/co/hconnect/repository/UserDao.java b/src/main/java/kr/co/hconnect/repository/UserDao.java
index a80419f..bf2a2b8 100644
--- a/src/main/java/kr/co/hconnect/repository/UserDao.java
+++ b/src/main/java/kr/co/hconnect/repository/UserDao.java
@@ -45,6 +45,14 @@ public void updateUser(UserVO vo) {
update("kr.co.hconnect.sqlmapper.updateUser",vo);
}
+ /**
+ * 로그인 정보 업데이트
+ * @param vo UserVO
+ */
+ public void updateUserLoginInfo(UserVO vo) {
+ update("kr.co.hconnect.sqlmapper.updateUserLoginInfo", vo);
+ }
+
/**
*유저정보 삭제
* @param userId 유저Id
diff --git a/src/main/java/kr/co/hconnect/rest/UserLoginRestController.java b/src/main/java/kr/co/hconnect/rest/UserLoginRestController.java
new file mode 100644
index 0000000..751d86c
--- /dev/null
+++ b/src/main/java/kr/co/hconnect/rest/UserLoginRestController.java
@@ -0,0 +1,79 @@
+package kr.co.hconnect.rest;
+
+import kr.co.hconnect.common.ApiResponseCode;
+import kr.co.hconnect.domain.UserLoginInfo;
+import kr.co.hconnect.domain.UserLoginResponse;
+import kr.co.hconnect.exception.InvalidRequestArgumentException;
+import kr.co.hconnect.exception.NotFoundUserInfoException;
+import kr.co.hconnect.exception.NotMatchPatientPasswordException;
+import kr.co.hconnect.jwt.TokenProvider;
+import kr.co.hconnect.service.UserService;
+import kr.co.hconnect.vo.UserVO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+@CrossOrigin
+@RestController
+@RequestMapping("/api")
+public class UserLoginRestController {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(UserLoginRestController.class);
+
+ private final TokenProvider tokenProvider;
+
+ /**
+ * 사용자 서비스
+ */
+ private final UserService userService;
+
+ /**
+ * 생성자
+ * @param tokenProvider Token 관리
+ * @param userService 사용자 서비스
+ */
+ public UserLoginRestController(TokenProvider tokenProvider, UserService userService) {
+ this.tokenProvider = tokenProvider;
+ this.userService = userService;
+ }
+
+ /**
+ * 로그인 정보 확인
+ */
+ @RequestMapping(value="/userLogin", method = RequestMethod.POST)
+ public UserLoginResponse checkLogin(@Valid @RequestBody UserLoginInfo userLoginInfo, BindingResult bindingResult) {
+ if (bindingResult.hasErrors()) {
+ throw new InvalidRequestArgumentException(bindingResult);
+ }
+
+ UserLoginResponse userLoginResponse = new UserLoginResponse();
+
+ try {
+ // 로그인 정보 조회
+ UserVO userVO = userService.selectLoginInfo(userLoginInfo);
+
+ // 사용자 로그인 정보 업데이트
+ userVO.setRememberYn(userLoginInfo.getRememberYn());
+ userService.updateUserLoginInfo(userVO);
+
+ // Token 발행
+ String token = tokenProvider.createUserToken(userVO);
+
+ userLoginResponse.setCode(ApiResponseCode.SUCCESS.getCode());
+ userLoginResponse.setMessage("로그인 성공");
+ userLoginResponse.setToken(token);
+ } catch (NotFoundUserInfoException e) {
+ userLoginResponse.setCode(ApiResponseCode.NOT_FOUND_USER_INFO.getCode());
+ userLoginResponse.setMessage(e.getMessage());
+ } catch (NotMatchPatientPasswordException e) {
+ userLoginResponse.setCode(ApiResponseCode.NOT_MATCH_PATIENT_PASSWORD.getCode());
+ userLoginResponse.setMessage(e.getMessage());
+ }
+
+ return userLoginResponse;
+ }
+
+}
diff --git a/src/main/java/kr/co/hconnect/service/UserService.java b/src/main/java/kr/co/hconnect/service/UserService.java
index 3fb40e7..38c5fa2 100644
--- a/src/main/java/kr/co/hconnect/service/UserService.java
+++ b/src/main/java/kr/co/hconnect/service/UserService.java
@@ -4,17 +4,21 @@
import egovframework.rte.fdl.cmmn.exception.FdlException;
import egovframework.rte.fdl.idgnr.EgovIdGnrService;
import kr.co.hconnect.common.CryptoUtils;
+import kr.co.hconnect.domain.UserLoginInfo;
+import kr.co.hconnect.exception.NotFoundUserInfoException;
+import kr.co.hconnect.exception.NotMatchPatientPasswordException;
import kr.co.hconnect.repository.UserDao;
-import kr.co.hconnect.vo.LoginVO;
import kr.co.hconnect.vo.UserVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
+import java.util.Locale;
/**
* 사용자 서비스
@@ -25,18 +29,30 @@ public class UserService extends EgovAbstractServiceImpl {
private static final Logger LOGGER = LoggerFactory.getLogger(UserService.class);
- private final UserDao userDao; // 사용자 Dao
- private final EgovIdGnrService userIdGnrService; // 사용자ID 채번 서비스
+ /**
+ * 사용자 Dao
+ */
+ private final UserDao userDao;
+ /**
+ * 사용자ID 채번 서비스
+ */
+ private final EgovIdGnrService userIdGnrService;
+ /**
+ * MessageSource
+ */
+ private final MessageSource messageSource;
/**
* 생성자
* @param userDao 사용자 Dao
* @param userIdGnrService 사용자ID 채번 서비스
+ * @param messageSource MessageSource
*/
@Autowired
- public UserService(UserDao userDao, @Qualifier("userIdGnrService") EgovIdGnrService userIdGnrService) {
+ public UserService(UserDao userDao, @Qualifier("userIdGnrService") EgovIdGnrService userIdGnrService, MessageSource messageSource) {
this.userDao = userDao;
this.userIdGnrService = userIdGnrService;
+ this.messageSource = messageSource;
}
/**
@@ -52,30 +68,27 @@ public UserVO selectUserInfo(String userId) {
userVO.setPassword(CryptoUtils.decrypt(userVO.getPassword()));
return userVO;
}
-
+
/**
* 로그인 정보 조회
- * @param userId 사용자ID
- * @param password 패스워드
+ * @param userLoginInfo UserLoginInfo
* @return 로그인VO
*/
- public LoginVO selectLoginInfo(String userId, String password) {
+ //public LoginVO selectLoginInfo(String userId, String password) {
+ public UserVO selectLoginInfo(UserLoginInfo userLoginInfo)
+ throws NotFoundUserInfoException, NotMatchPatientPasswordException {
// 사용자 정보 조회
- LoginVO loginVO = new LoginVO();
- UserVO userVO = selectUserInfo(userId);
-
- // 로그인 성공 여부 확인
- if (userVO == null) {
- loginVO.setFailMessage("사용자 정보를 확인하세요.");
- } else {
- // 암호확인
- if (!password.equals(userVO.getPassword())) {
- loginVO.setFailMessage("암호를 확인하세요.");
- }
- }
-
- loginVO.setUserVO(userVO);
- return loginVO;
+ UserVO userVO = selectUserInfo(userLoginInfo.getLoginId());
+
+ if (userVO == null) {
+ throw new NotFoundUserInfoException(messageSource.getMessage("message.notfound.userInfo"
+ ,null, Locale.getDefault()));
+ } else if (userVO.getPassword().equals(userLoginInfo.getPassword())) {
+ throw new NotMatchPatientPasswordException(messageSource.getMessage("message.mismatch.password"
+ , null, Locale.getDefault()));
+ }
+
+ return userVO;
}
/**
@@ -141,6 +154,15 @@ public void updateUser(UserVO vo) {
userDao.updateUser(vo);
}
+ /**
+ * 로그인 정보 업데이트
+ * @param vo UserVO
+ */
+ @Transactional(rollbackFor = Exception.class)
+ public void updateUserLoginInfo(UserVO vo) {
+ userDao.updateUserLoginInfo(vo);
+ }
+
/**
* 사용자 삭제
* @param userId 사용자Id
diff --git a/src/main/java/kr/co/hconnect/vo/UserVO.java b/src/main/java/kr/co/hconnect/vo/UserVO.java
index 1f486af..181078e 100644
--- a/src/main/java/kr/co/hconnect/vo/UserVO.java
+++ b/src/main/java/kr/co/hconnect/vo/UserVO.java
@@ -1,7 +1,6 @@
package kr.co.hconnect.vo;
import kr.co.hconnect.common.BaseDefaultVO;
-
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@@ -38,7 +37,13 @@ public class UserVO extends BaseDefaultVO {
* 리마크
*/
private String remark;
-
- //센터명
+ /**
+ * 센터명
+ */
private String centerNm;
+ /**
+ * 로그인 유지 여부
+ */
+ private String rememberYn;
+
}
diff --git a/src/main/resources/config/context-common.xml b/src/main/resources/config/context-common.xml
index 49caa44..0a3ae00 100644
--- a/src/main/resources/config/context-common.xml
+++ b/src/main/resources/config/context-common.xml
@@ -114,6 +114,11 @@
POST
+
+
+ POST
+
+
diff --git a/src/main/resources/message/message-common.properties b/src/main/resources/message/message-common.properties
index 6251779..d56eabd 100644
--- a/src/main/resources/message/message-common.properties
+++ b/src/main/resources/message/message-common.properties
@@ -76,6 +76,7 @@ message.notfound.loginId=해당 로그인 아이디가 존재하지 않습니다
message.notfound.notice=신규 알림이 없습니다
message.notfound.searchResultList=측정결과가 존재하지 않습니다
message.notfound.searchQuarantine=격리상태 내역이 존재하지 않습니다
+message.notfound.userInfo=사용자 정보가 존재하지 않습니다
# message - Duplicate
message.duplicate.admissionInfo=중복된 격리/입소내역이 존재합니다
message.duplicate.patientInfo=동일한 환자정보가 존재합니다
diff --git a/src/main/resources/sqlmapper/user.xml b/src/main/resources/sqlmapper/user.xml
index cf8e625..032a705 100644
--- a/src/main/resources/sqlmapper/user.xml
+++ b/src/main/resources/sqlmapper/user.xml
@@ -10,6 +10,7 @@
, USER_NM AS USER_NM -- 사용자명
, CENTER_ID AS CENTER_ID -- 센터ID
, REMARK AS REMARK -- 리마크
+ , REMEMBER_YN AS REMEMBER_YN -- 로그인 유지 여부
, REG_ID AS REG_ID -- 등록자ID
, REG_DT AS REG_DT -- 등록일시
, UPD_ID AS UPD_ID -- 수정자ID
@@ -72,6 +73,15 @@
]]>
+
+
+
+
+