feat: Client 정보 획득 DTO 추가

dev
gitea-관리자 12 months ago
parent 78f32f9db5
commit 71c07a4b88

@ -8,9 +8,12 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.xit.biz.auth.service.IAuthService;
import kr.xit.core.consts.Constants;
import kr.xit.core.consts.Constants.JwtToken;
import kr.xit.core.model.ApiResponseDTO;
import kr.xit.core.model.ClientInfoDTO;
import kr.xit.core.model.IApiResponse;
import kr.xit.core.model.TokenDTO;
import kr.xit.core.spring.auth.jwt.JwtTokenProvider;
@ -25,6 +28,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.ModelAndView;
/**
* <pre>
@ -45,7 +49,7 @@ import org.springframework.web.context.request.RequestContextHolder;
@Tag(name = "AuthApiController", description = "인증 관리")
@RequiredArgsConstructor
@RestController
@RequestMapping(value = "/biz/auth")
@RequestMapping(value = "/auth")
public class AuthController {
@Value("${app.token.saveType:header}")
private String authSaveType;
@ -59,6 +63,12 @@ public class AuthController {
private final MessageUtil messageUtil;
private final JwtTokenProvider jwtTokenProvider;
@Operation(summary = "로그인" , description = "로그인")
@GetMapping(value = "/loginForm")
public ModelAndView login() {
return new ModelAndView("/auth/loginForm.html");
}
/**
*
* @param loginVO , LoginVO
@ -127,7 +137,8 @@ public class AuthController {
)
@Operation(summary = "로그인(JWT)" , description = "로그인(JWT)")
@PostMapping(value = "/loginJwt")
public IApiResponse loginJWT(@RequestBody final LoginVO loginVO, HttpServletRequest request) {
public IApiResponse loginJWT(@RequestBody final LoginVO loginVO, ClientInfoDTO clientInfo, final HttpServletRequest request, final HttpServletResponse response) {
HashMap<String, Object> resultMap = new HashMap<String, Object>();
// 1. 일반 로그인 처리
@ -175,6 +186,7 @@ public class AuthController {
resultMap.put("resultVO", loginResultVO);
resultMap.put("token", tokenDTO);
response.setHeader(JwtToken.HEADER_NAME.getCode(), String.format("%s %s", JwtToken.GRANT_TYPE.getCode(), tokenDTO.getAccessToken()));
return ApiResponseDTO.success(resultMap);
}

@ -0,0 +1,38 @@
package kr.xit.core.model;
import kr.xit.core.spring.config.WebServerConfig;
import kr.xit.core.spring.resolver.ClientInfoArgumentResolver;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
/**
* <pre>
* description : Client class
* set
* -> 1. HandlerMethodArgumentResolver ClientInfoDTO
* 2. WebMvcConfigurer Resolver
* 3. Controller .
* packageName : kr.xit.core.model
* fileName : ClientInfoDTO
* author : limju
* date : 2023-04-26
* ======================================================================
*
* ----------------------------------------------------------------------
* 2023-04-26 limju
*
* </pre>
* @see ClientInfoArgumentResolver
* @see WebServerConfig
*/
@Getter
@AllArgsConstructor
@ToString
@Builder
public class ClientInfoDTO {
private final String channel;
private final String clientAddress;
}

@ -28,7 +28,7 @@ public class SpringDocsApiConfig {
return GroupedOpenApi.builder()
.group("1. Authentification API")
.pathsToMatch(
"/biz/auth/**"
"/auth/**"
)
.build();
}

@ -0,0 +1,32 @@
package kr.xit.core.spring.config;
import java.util.List;
import kr.xit.core.model.ClientInfoDTO;
import kr.xit.core.spring.resolver.ClientInfoArgumentResolver;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* <pre>
* description : Web server
* packageName : kr.xit.core.spring.config
* fileName : WebServerConfig
* author : limju
* date : 2023-04-26
* ======================================================================
*
* ----------------------------------------------------------------------
* 2023-04-26 limju
*
* </pre>
* @see ClientInfoDTO
* @see WebServerConfig
*/
@Configuration
public class WebServerConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new ClientInfoArgumentResolver());
}
}

@ -0,0 +1,50 @@
package kr.xit.core.spring.resolver;
import kr.xit.core.model.ClientInfoDTO;
import kr.xit.core.spring.config.WebServerConfig;
import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
/**
* <pre>
* description : Client ClientInfoDTO
* HandlerMethodArgumentResolver ClientInfoDTO
* -> WebMvcConfigurer Resolver
* packageName : kr.xit.core.spring.resolver
* fileName : ClientInfoArgumentResolver
* author : limju
* date : 2023-04-26
* ======================================================================
*
* ----------------------------------------------------------------------
* 2023-04-26 limju
*
* </pre>
* @see ClientInfoDTO
* @see WebServerConfig
*/
public class ClientInfoArgumentResolver implements HandlerMethodArgumentResolver {
private static final String HEADER_CHANNEL = "X-APP-CHANNEL";
private static final String HEADER_CLIENT_IP = "X-FORWORD-FOR";
@Override
public boolean supportsParameter(MethodParameter parameter) {
return ClientInfoDTO.class.equals(parameter.getParameterType());
}
@Override
public Object resolveArgument(@Nullable MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
String channel = webRequest.getHeader(HEADER_CHANNEL);
String clientAddress = webRequest.getHeader(HEADER_CLIENT_IP);
return new ClientInfoDTO(channel, clientAddress);
}
}

@ -24,8 +24,12 @@ app:
spring:
security:
white-list:
favicon.ico,
/,
/auth/login
/semantic/**
/auth/loginForm*,
/auth/login*,
/auth/loginJwt*,
/api-docs/**,
/swagger-resources,
/swagger-ui.html,
@ -57,6 +61,12 @@ spring:
- common
- auth
- app
# mvc:
# static-path-pattern: /resources/static/**
# view:
# prefix:
# suffix: .html
batch:
jdbc:

@ -0,0 +1,66 @@
<!DOCTYPE HTML>
<html lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="/resources/static/semantic/dist/semantic.min.css">
<script
src="https://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>
<script src="/resources/static/semantic/dist/semantic.min.js"></script>
<title>login</title>
</head>
<body>
<form class="ui form">
<div class="field">
<label>id</label>
<input type="text" name="id" placeholder="사용자 ID" value="admin">
</div>
<div class="field">
<label>password</label>
<input type="text" name="password" placeholder="비밀번호" value="1">
</div>
<div class="field">
<div class="ui checkbox">
<input type="checkbox" tabindex="0" class="hidden">
<label>id 저장</label>
</div>
</div>
<input type="hidden" name="userSe" value="USR">
<button class="ui button" type="submit">Submit</button>
</form>
</body>
<script>
const postForm = (body) => {
return fetch('/auth/loginJwt', {
method: 'POST',
headers: {
'X-APP-CHANNEL': 'WEB',
'X-FORWORD-FOR': '211.119.124.73',
'Content-Type': 'application/json'
},
body
});
};
const handleSubmit = async (e) => {
e.preventDefault();
const form = document.querySelector('form');
const data = Object.fromEntries(new FormData(form).entries());
// const body = {
// id: document.querySelector('input[name="id"]').value,
// password: document.querySelector('input[name="password"]').value,
// userSe: document.querySelector('input[name="userSe"]').value,
// }
const res = await postForm(JSON.stringify(data))
const json = await res.json();
console.log(json)
};
document.querySelector('form').addEventListener("click", handleSubmit);
</script>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save