로그인 로직 수정.
parent
c9d8933935
commit
5efe77b066
|
|
@ -16,38 +16,36 @@ export function requestFetch(url, requestOptions, handler, errorHandler) {
|
|||
console.log("requestFetch [requestOption] : ", requestOptions);
|
||||
|
||||
// Login 했을경우 JWT 설정
|
||||
const jToken = getLocalItem('jToken');
|
||||
const sessionUser = parseJwt(jToken);
|
||||
const accessToken = getLocalItem('accessToken');
|
||||
const sessionUser = parseJwt(accessToken);
|
||||
const sessionUserId = sessionUser?.id || null;
|
||||
const refreshToken = getLocalItem('refreshToken');
|
||||
if(sessionUserId != null){
|
||||
if( !requestOptions['headers'] ) requestOptions['headers']={}
|
||||
if( !requestOptions['headers']['Authorization'] ) requestOptions['headers']['Authorization']=null;
|
||||
requestOptions['headers']['Authorization'] = jToken;
|
||||
requestOptions['headers']['Authorization'] = accessToken;
|
||||
}
|
||||
|
||||
|
||||
//CORS ISSUE 로 인한 조치 - origin 및 credentials 추가
|
||||
//CORS ISSUE 로 인한 조치 - origin 및 credentials 추가
|
||||
// origin 추가
|
||||
if (!requestOptions['origin']) {
|
||||
requestOptions = { ...requestOptions, origin: SERVER_URL };
|
||||
}
|
||||
// credentials 추가
|
||||
// credentials 추가
|
||||
if (!requestOptions['credentials']) {
|
||||
requestOptions = { ...requestOptions, credentials: 'include' };
|
||||
}
|
||||
|
||||
fetch(SERVER_URL + url, requestOptions)
|
||||
.then(response => {// response Stream. Not completion object
|
||||
//console.log("requestFetch [Response Stream] ", response);
|
||||
//console.log("requestFetch [Response Stream] ", response);
|
||||
return response.json();
|
||||
})
|
||||
.then((resp) => {
|
||||
if (Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)) {
|
||||
alert("Login Alert"); //index.jsx라우터파일에 jwtAuthentication 함수로 공통 인증을 사용하는 코드 추가로 alert 원상복구
|
||||
setSessionItem('loginUser', {"id":""});
|
||||
window.location.href = URL.LOGIN;
|
||||
return false;
|
||||
//accessToken 갱신 요청
|
||||
accessTokenRefresh(url, requestOptions, handler, errorHandler);
|
||||
return resp;
|
||||
} else {
|
||||
return resp;
|
||||
}
|
||||
|
|
@ -79,4 +77,60 @@ export function requestFetch(url, requestOptions, handler, errorHandler) {
|
|||
console.log("requestFetch finally end");
|
||||
console.groupEnd("requestFetch");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function accessTokenRefresh(url, requestOptions, handler, errorHandler){
|
||||
requestOptions['headers']['Authorization'] = getLocalItem('refreshToken');
|
||||
if (!requestOptions['origin']) {
|
||||
requestOptions = { ...requestOptions, origin: SERVER_URL };
|
||||
}
|
||||
if (!requestOptions['credentials']) {
|
||||
requestOptions = { ...requestOptions, credentials: 'include' };
|
||||
}
|
||||
|
||||
fetch(SERVER_URL + "/auth/accessTokenRefresh", requestOptions)
|
||||
.then(response => {
|
||||
return response.json();
|
||||
})
|
||||
.then((resp) => {
|
||||
if(resp?.accessToken != null){
|
||||
setLocalItem('accessToken', resp.accessToken);
|
||||
requestFetch(url, requestOptions, handler, errorHandler);
|
||||
}else{
|
||||
// 갱신 실패
|
||||
alert("로그인이 해제되었습니다.");
|
||||
// index.jsx라우터파일에 jwtAuthentication 함수로 공통 인증을 사용하는 코드 추가로 alert 원상복구
|
||||
setLocalItem('accessToken', null);
|
||||
setLocalItem('refreshToken', null);
|
||||
window.location.href = URL.LOGIN;
|
||||
}
|
||||
})
|
||||
.then((resp) => {
|
||||
console.groupCollapsed("requestFetch.then()");
|
||||
console.log("requestFetch [response] ", resp);
|
||||
if (typeof handler === 'function') {
|
||||
handler(resp);
|
||||
} else {
|
||||
console.log('egov fetch handler not assigned!');
|
||||
}
|
||||
console.groupEnd("requestFetch.then()");
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('There was an error!', error);
|
||||
if (error === 'TypeError: Failed to fetch') {
|
||||
alert("서버와의 연결이 원활하지 않습니다. 서버를 확인하세요.");
|
||||
}
|
||||
|
||||
if (typeof errorHandler === 'function') {
|
||||
errorHandler(error);
|
||||
} else {
|
||||
console.error('egov error handler not assigned!');
|
||||
alert("ERR : " + error.message);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
console.log("requestFetch finally end");
|
||||
console.groupEnd("requestFetch");
|
||||
});
|
||||
}
|
||||
|
|
@ -13,8 +13,8 @@ function EgovHeader({ loginUser, onChangeLogin }) {
|
|||
console.group("EgovHeader");
|
||||
console.log("[Start] EgovHeader ------------------------------");
|
||||
|
||||
const jToken = getLocalItem('jToken');
|
||||
const userInfo = parseJwt(jToken);
|
||||
const accessToken = getLocalItem('accessToken');
|
||||
const userInfo = parseJwt(accessToken);
|
||||
const sessionUserId = userInfo?.id;
|
||||
const sessionUserSe = userInfo?.userSe;
|
||||
|
||||
|
|
@ -38,12 +38,11 @@ function EgovHeader({ loginUser, onChangeLogin }) {
|
|||
}
|
||||
EgovNet.requestFetch(logOutUrl, requestOptions,
|
||||
function (resp) {
|
||||
debugger
|
||||
console.log("===>>> logout resp= ", resp);
|
||||
if (parseInt(resp.resultCode) === parseInt(CODE.RCV_SUCCESS)) {
|
||||
onChangeLogin({ loginVO: {} });
|
||||
setLocalItem('loginUser', {"id":""});
|
||||
setLocalItem('jToken', null);
|
||||
setLocalItem('accessToken', null);
|
||||
setLocalItem('refreshToken', null);
|
||||
window.alert("로그아웃되었습니다!");
|
||||
navigate(URL.MAIN);
|
||||
|
|
|
|||
|
|
@ -342,6 +342,6 @@
|
|||
.modalYearInfoActive{color: #0d6efd}
|
||||
.modalDocInfoBtn{--bs-btn-padding-y: 0.1rem;--bs-btn-padding-x: 0.25rem;--bs-btn-font-size: 0.7rem; filter: grayscale(100%);}
|
||||
.modalDocInfoActive{filter: grayscale(0%);}
|
||||
.docInfoRow > .col{--bs-gutter-x: 0.5rem;}
|
||||
.docInfoRow > div{--bs-gutter-x: 0.5rem;}
|
||||
.bookmarkModalHeader{--bs-modal-title-line-height:1;}
|
||||
.optionBtn{--bs-btn-padding-y: 0.1rem;--bs-btn-padding-x: 0.25rem;--bs-btn-font-size: 0.7rem; margin-right: 7px;}
|
||||
|
|
@ -74,14 +74,13 @@ function EgovLoginContent(props) {
|
|||
EgovNet.requestFetch(loginUrl,
|
||||
requestOptions,
|
||||
(resp) => {
|
||||
let jToken = resp?.jToken || null;
|
||||
let resultVO = parseJwt(jToken);
|
||||
let accessToken = resp?.accessToken || null;
|
||||
let resultVO = parseJwt(accessToken);
|
||||
let refreshToken = resp?.refreshToken || null;
|
||||
|
||||
// setSessionItem('jToken', jToken);
|
||||
setLocalItem('jToken', jToken);
|
||||
// setSessionItem('accessToken', accessToken);
|
||||
setLocalItem('accessToken', accessToken);
|
||||
setLocalItem('refreshToken', refreshToken);
|
||||
debugger
|
||||
if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) {
|
||||
// setSessionItem('loginUser', resultVO);
|
||||
props.onChangeLogin(resultVO);
|
||||
|
|
|
|||
|
|
@ -45,9 +45,9 @@ function Join(props) {
|
|||
requestOptions,
|
||||
(resp) => {
|
||||
let resultVO = resp.resultVO;
|
||||
let jToken = resp?.jToken || null;
|
||||
let accessToken = resp?.accessToken || null;
|
||||
|
||||
setSessionItem('jToken', jToken);
|
||||
setLocalItem('accessToken', accessToken);
|
||||
if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) {
|
||||
alert(resp.resultMessage);
|
||||
navigate('/login');
|
||||
|
|
|
|||
|
|
@ -80,26 +80,31 @@ const BookmarkModal = ({docCode, docPart, ymd}) => {
|
|||
let buttonClass = "btn btn-sm modalDocInfoBtn "
|
||||
let pClass = "modalYearInfo ";
|
||||
if(item.doc_er === 'E'){
|
||||
buttonClass += "btn-outline-success "
|
||||
buttonClass += "btn-success "
|
||||
}else{
|
||||
buttonClass += "btn-outline-primary "
|
||||
buttonClass += "btn-primary "
|
||||
}
|
||||
if(index === activeIndex){
|
||||
pClass += "modalYearInfoActive"
|
||||
buttonClass += "modalDocInfoActive"
|
||||
}
|
||||
optionTag.push(
|
||||
<Col>
|
||||
<Col xs={"auto"}>
|
||||
<input type="button"
|
||||
className={buttonClass}
|
||||
value={item.doc_er==='E'?'재':'개'}
|
||||
value={item.doc_er==='E'?'제':'개'}
|
||||
onClick={docInfoSelectorChange}
|
||||
data-ymd={item.estb_ymd}/>
|
||||
data-ymd={item.rvsn_ymd}/>
|
||||
<br/>
|
||||
<p className={pClass}>{item.doc_yr}</p>
|
||||
</Col>)
|
||||
})
|
||||
headTag.push(<Row className="docInfoRow"><Col className="docInfoTitle">{docCode} {docTitle}</Col>{optionTag}</Row>)
|
||||
headTag.push(
|
||||
<Row className="docInfoRow justify-content-start">
|
||||
<Col xs={"auto"} className="docInfoTitle">{docCode} {docTitle}</Col>
|
||||
{optionTag}
|
||||
</Row>
|
||||
)
|
||||
}else{
|
||||
headTag.push(<div>검색된 결과가 없습니다.</div>); // 코드 목록 초기값
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ const SbItem = ({item, openDocCode, updateDocCode}) => {
|
|||
nextOpenDoc.className = nextOpenDoc.className+' openDoc';
|
||||
}
|
||||
|
||||
if(item.childrens.length > 0){
|
||||
if(item.group_yn==='Y'){
|
||||
const icon1 = collapsed?<AiOutlinePlusSquare />:<AiOutlineMinusSquare />;
|
||||
const icon2 = collapsed?<FcOpenedFolder />:<FcFolder />;
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ function CodeViewer(props) {
|
|||
const [bookMarkModal, setBookMarkModal] = useState();
|
||||
|
||||
|
||||
const sessionUser = parseJwt(getLocalItem('jToken'));
|
||||
const sessionUser = parseJwt(getLocalItem('accessToken'));
|
||||
const sessionUserSe = sessionUser?.userSe;
|
||||
|
||||
const handleClose = () => setShow(false);
|
||||
|
|
@ -141,7 +141,9 @@ function CodeViewer(props) {
|
|||
className={buttonClass}
|
||||
value={item.doc_er==='E'?'제':'개'}
|
||||
onClick={docInfoSelectorChange}
|
||||
data-ymd={item.rvsn_ymd} data-doccode={item.kcsc_cd}/>
|
||||
data-ymd={item.rvsn_ymd}
|
||||
data-doccode={item.kcsc_cd}
|
||||
data-docinfoseq={item.doc_info_seq}/>
|
||||
<br/>
|
||||
<p className={pClass}>{item.doc_yr}</p>
|
||||
</Col>)
|
||||
|
|
@ -256,18 +258,18 @@ function CodeViewer(props) {
|
|||
}
|
||||
if(item.error_cd !== null){
|
||||
if(sessionUserSe === "ADM"){
|
||||
item.full_content = "<p class='errorText' id='error"+item.cont_type_cd+"'>"+item.error_cd+"</p><br>"+
|
||||
item.full_content = "<p class='errorText' id='error"+item.doc_cont_seq+"'>"+item.error_cd+"</p><br>"+
|
||||
"<div class='input-group w-25 d-none errorEditDiv'>" +
|
||||
"<input type='hidden' class='contTypeCd' value='"+item.cont_type_cd+"' />"+
|
||||
"<input type='hidden' class='docContSeq' value='"+item.doc_cont_seq+"' />"+
|
||||
"<input type='text' class='form-control form-control-sm errorCd' value='"+item.error_cd+"'/>"+
|
||||
"<button class='btn btn-sm btn-primary errorEditSaveBtn'>저장</button>"+
|
||||
"<button class='btn btn-sm btn-secondary errorEditCancelBtn'>취소</button>"+
|
||||
"</div>"+
|
||||
item.full_content;
|
||||
}else{
|
||||
item.full_content = "<p class='errorText' id='error"+item.cont_type_cd+"'>"+item.error_cd+"</p><br>"+item.full_content;
|
||||
item.full_content = "<p class='errorText' id='error"+item.doc_cont_seq+"'>"+item.error_cd+"</p><br>"+item.full_content;
|
||||
}
|
||||
optionTag.push(<option value={item.cont_type_cd}>{item.error_cd}</option>)
|
||||
optionTag.push(<option value={item.doc_cont_seq}>{item.error_cd}</option>)
|
||||
}
|
||||
item.full_content = item.full_content+"<hr>"
|
||||
detailTag.push(
|
||||
|
|
@ -368,8 +370,7 @@ function CodeViewer(props) {
|
|||
saveBtn.onclick = (e) => {
|
||||
const errorEditDiv = e.target.parentElement;
|
||||
const content = {
|
||||
docInfoSeq: document.querySelector("#docInfoSelector").value,
|
||||
contTypeCd: errorEditDiv.querySelector(".contTypeCd").value,
|
||||
docContSeq: errorEditDiv.querySelector(".docContSeq").value,
|
||||
errorCd: errorEditDiv.querySelector(".errorCd").value
|
||||
}
|
||||
saveErrorCd(content, errorEditDiv)
|
||||
|
|
@ -399,7 +400,7 @@ function CodeViewer(props) {
|
|||
|
||||
function saveErrorCd(content, errorEditDiv){
|
||||
EgovNet.requestFetch(
|
||||
'/standardCode/saveErrorCd.do',
|
||||
'/standardCode/auth/saveErrorCd.do',
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
|
|
@ -411,6 +412,8 @@ function CodeViewer(props) {
|
|||
if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) {
|
||||
alert("저장되었습니다.")
|
||||
errorEditDiv.parentElement.querySelector(".errorText").innerText = content.errorCd
|
||||
}else if(Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)){
|
||||
console.log("토큰 갱신중.")
|
||||
}else{
|
||||
alert("저장에 실패하였습니다.")
|
||||
}
|
||||
|
|
@ -468,8 +471,8 @@ function CodeViewer(props) {
|
|||
}
|
||||
|
||||
CodeViewer.defaultProps = {
|
||||
docCode: 'KDS 24 14 21',
|
||||
docName: '교량 설계 일반사항(한계상태설계법)'
|
||||
docCode: 'KCS 24 31 10',
|
||||
docName: '용접(한계상태설계법)'
|
||||
}
|
||||
|
||||
export default CodeViewer;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.dbnt.kcscbackend.auth;
|
||||
|
||||
import com.dbnt.kcscbackend.auth.entity.UserInfo;
|
||||
import com.dbnt.kcscbackend.auth.service.EgovLoginService;
|
||||
import com.dbnt.kcscbackend.config.common.BaseController;
|
||||
import com.dbnt.kcscbackend.auth.entity.LoginVO;
|
||||
|
|
@ -15,6 +16,7 @@ import lombok.RequiredArgsConstructor;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.validation.Errors;
|
||||
|
|
@ -48,6 +50,7 @@ import java.util.List;
|
|||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/auth")
|
||||
@Tag(name="EgovLoginApiController",description = "로그인 관련")
|
||||
public class EgovLoginApiController extends BaseController {
|
||||
|
|
@ -56,6 +59,8 @@ public class EgovLoginApiController extends BaseController {
|
|||
@Resource(name = "loginService")
|
||||
private EgovLoginService loginService;
|
||||
|
||||
private final EgovJwtTokenUtil egovJwtTokenUtil;
|
||||
|
||||
/** EgovMessageSource */
|
||||
@Resource(name = "egovMessageSource")
|
||||
EgovMessageSource egovMessageSource;
|
||||
|
|
@ -83,26 +88,39 @@ public class EgovLoginApiController extends BaseController {
|
|||
msg.append(error.getDefaultMessage());
|
||||
msg.append("\n");
|
||||
}
|
||||
resultMap.put("resultCode", "300");
|
||||
resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
|
||||
resultMap.put("resultMessage", msg.toString());
|
||||
}else if(!loginVO.getPassword().equals(loginVO.getPasswordChk())){
|
||||
resultMap.put("resultCode", "300");
|
||||
resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
|
||||
resultMap.put("resultMessage", "비밀번호 확인이 잘못 입력되었습니다.");
|
||||
}else{
|
||||
Integer insertResult = loginService.insertUser(loginVO);
|
||||
|
||||
if(insertResult!=null){
|
||||
resultMap.put("resultCode", "200");
|
||||
resultMap.put("resultCode", ResponseCode.SUCCESS.getCode());
|
||||
resultMap.put("resultMessage", "저장 되었습니다.");
|
||||
}else{
|
||||
resultMap.put("resultCode", "300");
|
||||
resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
|
||||
resultMap.put("resultMessage", "저장에 실패하였습니다.");
|
||||
}
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
@RequestMapping("/auth/loginSuccess")
|
||||
@RequestMapping("/accessTokenRefresh")
|
||||
public HashMap<String, Object> accessTokenRefresh(HttpServletRequest request, HttpServletResponse response, @AuthenticationPrincipal UserInfo loginVO){
|
||||
HashMap<String, Object> resultMap = new HashMap<>();
|
||||
String token = egovJwtTokenUtil.accessTokenRefresh(request.getHeader("Authorization"));
|
||||
if(token!=null){
|
||||
resultMap.put("resultCode", ResponseCode.SUCCESS.getCode());
|
||||
resultMap.put("accessToken", token);
|
||||
}else{
|
||||
resultMap.put("resultCode", ResponseCode.AUTH_ERROR.getCode());
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
@RequestMapping("/loginSuccess")
|
||||
public HashMap<String, Object> loginSuccess(HttpServletRequest request, HttpServletResponse response){
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ public class EgovJwtTokenUtil implements Serializable{
|
|||
public static final String SECRET_KEY = EgovProperties.getProperty("Globals.jwt.secret");
|
||||
|
||||
private final RefreshTokenRepository refreshTokenRepository;
|
||||
public static final long JWT_ACCESS_VALID_TIME = (30*60*1000); //엑세스 토큰의 유효시간 설정, 30분
|
||||
public static final long JWT_REFRESH_VALID_TIME = (60*60*24*14*1000); //리프레시 토큰의 유효시간 설정, 2주
|
||||
|
||||
|
||||
//retrieve username from jwt token
|
||||
|
|
@ -69,8 +71,7 @@ public class EgovJwtTokenUtil implements Serializable{
|
|||
return claims.get(type).toString();
|
||||
}
|
||||
public Claims getClaimFromToken(String token) {
|
||||
final Claims claims = getAllClaimsFromToken(token);
|
||||
return claims;
|
||||
return getAllClaimsFromToken(token);
|
||||
}
|
||||
|
||||
//for retrieveing any information from token we will need the secret key
|
||||
|
|
@ -104,15 +105,31 @@ public class EgovJwtTokenUtil implements Serializable{
|
|||
return builder.compact();
|
||||
}
|
||||
|
||||
public String generateAccessToken(UserInfo loginVO, String remoteAddr, Long sec) {
|
||||
return generateToken(loginVO, remoteAddr, sec);
|
||||
public String generateAccessToken(UserInfo loginVO, String remoteAddr) {
|
||||
return generateToken(loginVO, remoteAddr, JWT_ACCESS_VALID_TIME);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public String generateRefreshTokenToken(UserInfo loginVO, String remoteAddr, Long sec){
|
||||
RefreshToken refreshToken = new RefreshToken(loginVO.getUserSeq(), generateToken(loginVO, remoteAddr, sec), remoteAddr);
|
||||
public String generateRefreshTokenToken(UserInfo loginVO, String remoteAddr){
|
||||
String token = generateToken(loginVO, remoteAddr, JWT_REFRESH_VALID_TIME);
|
||||
RefreshToken refreshToken = new RefreshToken(loginVO.getUserSeq(), token);
|
||||
refreshTokenRepository.save(refreshToken);
|
||||
return refreshToken.getRefreshToken();
|
||||
}
|
||||
|
||||
public String accessTokenRefresh(String token){
|
||||
RefreshToken refreshToken = refreshTokenRepository.findByRefreshToken(token).orElse(null);
|
||||
if(refreshToken!=null){
|
||||
Claims claims = getClaimFromToken(refreshToken.getRefreshToken());
|
||||
JwtBuilder builder = Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.setSubject("Authorization")
|
||||
.setIssuedAt(new Date(System.currentTimeMillis()))
|
||||
.setExpiration(new Date(System.currentTimeMillis() + JWT_ACCESS_VALID_TIME))
|
||||
.signWith(Keys.hmacShaKeyFor(SECRET_KEY.getBytes(StandardCharsets.UTF_8)), SignatureAlgorithm.HS512);
|
||||
return builder.compact();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||
// step 1. request header에서 토큰을 가져온다.
|
||||
String jwtToken = EgovStringUtil.isNullToString(req.getHeader(HEADER_STRING));
|
||||
|
||||
|
||||
// step 2. 토큰에 내용이 있는지 확인해서 id값을 가져옴
|
||||
// Exception 핸들링 추가처리 (토큰 유효성, 토큰 변조 여부, 토큰 만료여부)
|
||||
// 내부적으로 parse하는 과정에서 해당 여부들이 검증됨
|
||||
|
|
@ -60,6 +59,8 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||
logger.debug("===>>> id = " + id);
|
||||
} catch (IllegalArgumentException | ExpiredJwtException | MalformedJwtException | UnsupportedJwtException | SignatureException e) {
|
||||
logger.debug("Unable to verify JWT Token: " + e.getMessage());
|
||||
req.setAttribute("errorType", e.getClass().getName());
|
||||
req.setAttribute("errorMsg", e.getMessage());
|
||||
verificationFlag = false;
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +69,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||
logger.debug("jwtToken validated");
|
||||
loginVO.setId(id);
|
||||
loginVO.setUserSe( jwtTokenUtil.getUserSeFromToken(jwtToken) );
|
||||
loginVO.setUniqId( jwtTokenUtil.getInfoFromToken("uniqId",jwtToken) );
|
||||
// loginVO.setUniqId( jwtTokenUtil.getInfoFromToken("uniqId",jwtToken) );
|
||||
// loginVO.setOrgnztId( jwtTokenUtil.getInfoFromToken("orgnztId",jwtToken) );
|
||||
// loginVO.setName( jwtTokenUtil.getInfoFromToken("name",jwtToken) );
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,5 @@ public class RefreshToken {
|
|||
private Integer userSeq;
|
||||
@Indexed
|
||||
private String refreshToken;
|
||||
private String remoteAddr;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@ public class CustomUrlAuthenticationSuccessHandler extends SimpleUrlAuthenticati
|
|||
|
||||
private final EgovJwtTokenUtil jwtTokenUtil;
|
||||
private RequestCache requestCache = new HttpSessionRequestCache();
|
||||
public static final long JWT_ACCESS_VALID_TIME = (30*60*1000); //엑세스 토큰의 유효시간 설정, 30분
|
||||
public static final long JWT_REFRESH_VALID_TIME = (60*60*24*14*1000); //리프레시 토큰의 유효시간 설정, 2주
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
|
|
@ -55,16 +53,15 @@ public class CustomUrlAuthenticationSuccessHandler extends SimpleUrlAuthenticati
|
|||
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
|
||||
MediaType jsonMimeType = MediaType.APPLICATION_JSON;
|
||||
|
||||
String jwtToken = jwtTokenUtil.generateAccessToken(securityUser, request.getRemoteAddr(), JWT_ACCESS_VALID_TIME);
|
||||
String refreshToken = jwtTokenUtil.generateRefreshTokenToken(securityUser, request.getRemoteAddr(), JWT_REFRESH_VALID_TIME);
|
||||
String accessToken = jwtTokenUtil.generateAccessToken(securityUser, request.getRemoteAddr());
|
||||
String refreshToken = jwtTokenUtil.generateRefreshTokenToken(securityUser, request.getRemoteAddr());
|
||||
HashMap<String, Object> resultMap = new HashMap<>();
|
||||
resultMap.put("resultCode", "200");
|
||||
resultMap.put("jToken", jwtToken);
|
||||
resultMap.put("accessToken", accessToken);
|
||||
resultMap.put("refreshToken", refreshToken);
|
||||
response.addHeader("Authorization", "BEARER "+jwtToken);
|
||||
Cookie refreshTokenCookie = new Cookie("refreshToken", refreshToken);
|
||||
refreshTokenCookie.setMaxAge((int)JWT_REFRESH_VALID_TIME/1000);
|
||||
response.addCookie(refreshTokenCookie);
|
||||
// response.addHeader("Authorization", "BEARER "+accessToken);
|
||||
// Cookie refreshTokenCookie = new Cookie("refreshToken", refreshToken);
|
||||
// response.addCookie(refreshTokenCookie);
|
||||
if (jsonConverter.canWrite(resultMap.getClass(), jsonMimeType)) {
|
||||
jsonConverter.write(resultMap, jsonMimeType, new ServletServerHttpResponse(response));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import com.dbnt.kcscbackend.config.jwt.JwtAuthenticationFilter;
|
|||
import com.dbnt.kcscbackend.config.jwt.redis.RefreshTokenRepository;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
|
@ -49,7 +48,7 @@ public class SecurityConfig {
|
|||
@Resource(name = "loginService")
|
||||
private UserDetailsService loginService;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final RefreshTokenRepository refreshTokenRepository;
|
||||
private final EgovJwtTokenUtil egovJwtTokenUtil;
|
||||
|
||||
//Http Methpd : Get 인증예외 List
|
||||
private String[] AUTH_GET_WHITELIST = {
|
||||
|
|
@ -63,6 +62,7 @@ public class SecurityConfig {
|
|||
"/",
|
||||
"/auth/login",
|
||||
"/login",
|
||||
"/auth/accessTokenRefresh", // jwt accessToken 갱신
|
||||
"/auth/join",//회원가입
|
||||
"/cmm/main/**.do", // 메인페이지
|
||||
"/cmm/fms/FileDown.do", //파일 다운로드
|
||||
|
|
@ -123,12 +123,13 @@ public class SecurityConfig {
|
|||
|
||||
http.cors().and().addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class)
|
||||
.exceptionHandling(exceptionHandlingConfigurer ->
|
||||
exceptionHandlingConfigurer
|
||||
.authenticationEntryPoint(new JwtAuthenticationEntryPoint())
|
||||
exceptionHandlingConfigurer.authenticationEntryPoint(new JwtAuthenticationEntryPoint())
|
||||
);
|
||||
|
||||
http.addFilterBefore(jsonUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
http.logout().logoutRequestMatcher(new AntPathRequestMatcher("/auth/logout")).logoutSuccessHandler(new CustomLogoutSuccessHandler());
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
|
@ -141,8 +142,7 @@ public class SecurityConfig {
|
|||
|
||||
@Bean
|
||||
public JsonAuthenticationFilter jsonUsernamePasswordAuthenticationFilter() {
|
||||
EgovJwtTokenUtil jwtTokenUtil = new EgovJwtTokenUtil(refreshTokenRepository);
|
||||
JsonAuthenticationFilter jsonAuthenticationFilter = new JsonAuthenticationFilter(objectMapper, new CustomUrlAuthenticationSuccessHandler(jwtTokenUtil), loginFailureHandler());
|
||||
JsonAuthenticationFilter jsonAuthenticationFilter = new JsonAuthenticationFilter(objectMapper, new CustomUrlAuthenticationSuccessHandler(egovJwtTokenUtil), loginFailureHandler());
|
||||
jsonAuthenticationFilter.setAuthenticationManager(authenticationManager());
|
||||
return jsonAuthenticationFilter;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ public class StandardCodeController extends BaseController {
|
|||
@ApiResponse(responseCode = "303", description = "만료된 토큰"),
|
||||
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
|
||||
})
|
||||
@RequestMapping(method = RequestMethod.POST, value = "/saveErrorCd.do", consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@RequestMapping(method = RequestMethod.POST, value = "/auth/saveErrorCd.do", consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResultVO saveErrorCd(@RequestBody TnDocumentContent content, @AuthenticationPrincipal LoginVO user, HttpServletRequest req) throws Exception {
|
||||
ResultVO resultVO = new ResultVO();
|
||||
Map<String, Object> resultMap = new HashMap<>();
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ public interface TnDocumentContentRepository extends JpaRepository<TnDocumentCon
|
|||
@Query(value = "select * from sp_get_recent_full_context_by_content(:docCode, :docPart, :ymd)", nativeQuery = true)
|
||||
List<StandardCodeContentInterface> spGetRecentFullContextByContent(String docCode, String docPart, String ymd);
|
||||
|
||||
Optional<TnDocumentContent> findByContTypeCd(String contTypeCd);
|
||||
|
||||
Optional<TnDocumentContent> findByDocInfoSeqAndContTypeCd(Integer docInfoSeq, String contTypeCd);
|
||||
Optional<TnDocumentContent> findByDocContSeq(Integer docContSeq);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public class StandardCodeService extends EgovAbstractServiceImpl {
|
|||
|
||||
@Transactional
|
||||
public void saveErrorCd(TnDocumentContent content) {
|
||||
TnDocumentContent saveContent = tnDocumentContentRepository.findByDocInfoSeqAndContTypeCd(content.getDocInfoSeq(), content.getContTypeCd()).orElse(null);
|
||||
TnDocumentContent saveContent = tnDocumentContentRepository.findByDocContSeq(content.getDocContSeq()).orElse(null);
|
||||
if(saveContent!=null){
|
||||
saveContent.setErrorCd(content.getErrorCd());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue