admin: form 기반 로그인 -> json http 기반 로그인으로 변경
This commit is contained in:
parent
e368414006
commit
b81ab51a11
|
|
@ -1,18 +1,24 @@
|
|||
package com.bpgroup.poc.admin.security;
|
||||
|
||||
import com.bpgroup.poc.admin.common.FormatHelper;
|
||||
import com.bpgroup.poc.admin.security.authentication.AuthenticationFailException;
|
||||
import com.bpgroup.poc.admin.security.authentication.LoginService;
|
||||
import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationFilter;
|
||||
import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationProvider;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.ProviderManager;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.security.web.header.writers.XXssProtectionHeaderWriter;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
|
|
@ -22,6 +28,8 @@ public class SecurityConfig {
|
|||
private static final String LOGOUT_PATH = "/logout";
|
||||
private static final String ERROR_PATH = "/error";
|
||||
|
||||
private final LoginService loginService;
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
// 보안 기본 설정
|
||||
|
|
@ -39,19 +47,8 @@ public class SecurityConfig {
|
|||
.requestMatchers(LOGIN_PATH, LOGOUT_PATH, ERROR_PATH).permitAll()
|
||||
.anyRequest().authenticated());
|
||||
|
||||
http.formLogin(c -> c
|
||||
.loginPage(LOGIN_PATH)
|
||||
.loginProcessingUrl(LOGIN_PATH)
|
||||
.usernameParameter("loginId")
|
||||
.passwordParameter("password")
|
||||
.defaultSuccessUrl("/main")
|
||||
.failureHandler((req, res, ex) -> {
|
||||
if (Objects.requireNonNull(ex) instanceof AuthenticationFailException authenticationFailException) {
|
||||
res.sendRedirect(FormatHelper.format(LOGIN_PATH + "?error={}", authenticationFailException.getReason()));
|
||||
} else {
|
||||
res.sendRedirect(ERROR_PATH);
|
||||
}
|
||||
}));
|
||||
http.formLogin(AbstractHttpConfigurer::disable); // Form 로그인이 아닌 Json 로그인으로 분리
|
||||
http.addFilterBefore(authenticationGenerateFilter(), UsernamePasswordAuthenticationFilter.class); // 로그인 관련 Filter 설정
|
||||
|
||||
http.logout(c -> c
|
||||
.logoutRequestMatcher(new AntPathRequestMatcher(LOGOUT_PATH, "GET"))
|
||||
|
|
@ -61,12 +58,23 @@ public class SecurityConfig {
|
|||
return http.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Bcrypt Version, Bcrypt Strength, Salt String 설정은 생성자를 이용하여 설정 가능
|
||||
*/
|
||||
@Bean
|
||||
public BCryptPasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
public CustomAuthenticationProvider customAuthenticationProvider() {
|
||||
return new CustomAuthenticationProvider(loginService);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager() {
|
||||
List<AuthenticationProvider> providers = new ArrayList<>();
|
||||
providers.add(customAuthenticationProvider());
|
||||
return new ProviderManager(providers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CustomAuthenticationFilter authenticationGenerateFilter() {
|
||||
CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
|
||||
filter.setAuthenticationManager(authenticationManager());
|
||||
return filter;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package com.bpgroup.poc.admin.security;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
|
||||
/**
|
||||
* SecurityConfig 에 있을 경우 Service 에 주입 시 순환 참조가 발생하여 별로 파일로 분리
|
||||
*/
|
||||
@Configuration
|
||||
public class SecurityEncryptConfig {
|
||||
/**
|
||||
* Bcrypt Version, Bcrypt Strength, Salt String 설정은 생성자를 이용하여 설정 가능
|
||||
*/
|
||||
@Bean
|
||||
public BCryptPasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package com.bpgroup.poc.admin.security.authentication;
|
||||
|
||||
import com.bpgroup.poc.admin.app.login.LoginResult;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
package com.bpgroup.poc.admin.security.authentication;
|
||||
|
||||
import com.bpgroup.poc.admin.app.login.exception.AdministratorNotFoundException;
|
||||
import com.bpgroup.poc.admin.app.login.exception.DoNotHaveAnyMenuException;
|
||||
import com.bpgroup.poc.admin.app.login.exception.InvalidPasswordException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public enum AuthenticationFailReason {
|
||||
WRONG_LOGIN_ID,
|
||||
WRONG_PASSWORD,
|
||||
HAVE_NO_MENU,
|
||||
INTERNAL_ERROR;
|
||||
|
||||
public static AuthenticationFailReason from(Exception e) {
|
||||
if (e instanceof AdministratorNotFoundException || e instanceof InvalidPasswordException) {
|
||||
return WRONG_LOGIN_ID;
|
||||
} else if (e instanceof DoNotHaveAnyMenuException) {
|
||||
return HAVE_NO_MENU;
|
||||
} else {
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.bpgroup.poc.admin.security.authentication;
|
||||
|
||||
import com.bpgroup.poc.admin.security.authentication.exception.AuthenticationFailException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
|
||||
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
|
||||
@Override
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
String failMessage = "시스템 오류가 발생했습니다.";
|
||||
|
||||
if (Objects.requireNonNull(exception) instanceof AuthenticationFailException authenticationFailException) {
|
||||
failMessage = authenticationFailException.getReason().getMessage();
|
||||
}
|
||||
|
||||
String jsonResponse = new ObjectMapper().writeValueAsString(
|
||||
LoginResponse.fail(
|
||||
"9999",
|
||||
failMessage
|
||||
)
|
||||
);
|
||||
response.getWriter().write(jsonResponse);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.bpgroup.poc.admin.security.authentication;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class CustomAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
|
||||
private static final String DEFAULT_LOGIN_REQUEST_URL = "/login";
|
||||
private static final String HTTP_METHOD = "POST";
|
||||
private static final String CONTENT_TYPE = "application/json";
|
||||
private boolean postOnly = true;
|
||||
|
||||
public CustomAuthenticationFilter() {
|
||||
super(new AntPathRequestMatcher(DEFAULT_LOGIN_REQUEST_URL, HTTP_METHOD)); // 위에서 설정한 /oauth2/login/* 의 요청에, GET으로 온 요청을 처리하기 위해 설정한다.
|
||||
setAuthenticationSuccessHandler(new CustomAuthenticationSuccessHandler());
|
||||
setAuthenticationFailureHandler(new CustomAuthenticationFailureHandler());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
|
||||
// 요청에 대한 유효성 검사
|
||||
isValidated(request);
|
||||
|
||||
LoginRequest loginRequest = new ObjectMapper().readValue(
|
||||
StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8),
|
||||
LoginRequest.class
|
||||
);
|
||||
|
||||
String username = loginRequest.getUsername();
|
||||
String password = loginRequest.getPassword();
|
||||
|
||||
if (username == null || password == null) {
|
||||
throw new AuthenticationServiceException("DATA IS MISS");
|
||||
}
|
||||
|
||||
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
|
||||
setDetails(request, authenticationToken);
|
||||
|
||||
return this.getAuthenticationManager().authenticate(authenticationToken);
|
||||
}
|
||||
|
||||
private void isValidated(HttpServletRequest request) {
|
||||
if (this.postOnly && !request.getMethod().equals(HTTP_METHOD)) {
|
||||
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
|
||||
}
|
||||
|
||||
if (request.getContentType() == null || !request.getContentType().equals(CONTENT_TYPE)) {
|
||||
throw new AuthenticationServiceException("Authentication Content-Type not supported: " + request.getContentType());
|
||||
}
|
||||
}
|
||||
|
||||
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
|
||||
authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,27 +1,28 @@
|
|||
package com.bpgroup.poc.admin.security.authentication;
|
||||
|
||||
import com.bpgroup.poc.admin.app.login.LoginResult;
|
||||
import com.bpgroup.poc.admin.app.login.LoginService;
|
||||
import com.bpgroup.poc.admin.security.authentication.exception.AuthenticationFailException;
|
||||
import com.bpgroup.poc.admin.security.authentication.exception.AuthenticationFailReason;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CustomAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
private final LoginService loginService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
String loginId = (String) authentication.getPrincipal();
|
||||
String password = (String) authentication.getCredentials();
|
||||
|
||||
try {
|
||||
LoginResult loginResult = loginService.login(loginId, password);
|
||||
String username = (String) authentication.getPrincipal();
|
||||
String password = (String) authentication.getCredentials();
|
||||
|
||||
LoginResult loginResult = loginService.login(username, password);
|
||||
|
||||
return buildAuthenticationToken(loginResult);
|
||||
} catch (Exception e) {
|
||||
throw new AuthenticationFailException("로그인에 실패하였습니다.", AuthenticationFailReason.from(e));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
package com.bpgroup.poc.admin.security.authentication;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
|
||||
@Override
|
||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {
|
||||
AuthenticationSuccessHandler.super.onAuthenticationSuccess(request, response, chain, authentication);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
|
||||
String jsonResponse = new ObjectMapper().writeValueAsString(
|
||||
LoginResponse.success(
|
||||
"token"
|
||||
)
|
||||
);
|
||||
|
||||
response.getWriter().write(jsonResponse);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.bpgroup.poc.admin.security.authentication;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 로그인 요청 Request
|
||||
*/
|
||||
@Data
|
||||
public class LoginRequest {
|
||||
private String username;
|
||||
private String password;
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.bpgroup.poc.admin.security.authentication;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
public class LoginResponse {
|
||||
|
||||
private String resultCode;
|
||||
private String resultMessage;
|
||||
private String token;
|
||||
|
||||
public static LoginResponse success(String token) {
|
||||
LoginResponse response = new LoginResponse();
|
||||
response.resultCode = "0000";
|
||||
response.resultMessage = "Success";
|
||||
response.token = token;
|
||||
return response;
|
||||
}
|
||||
|
||||
public static LoginResponse fail(String resultCode, String resultMessage) {
|
||||
LoginResponse response = new LoginResponse();
|
||||
response.resultCode = resultCode;
|
||||
response.resultMessage = resultMessage;
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.bpgroup.poc.admin.app.login;
|
||||
package com.bpgroup.poc.admin.security.authentication;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
package com.bpgroup.poc.admin.app.login;
|
||||
package com.bpgroup.poc.admin.security.authentication;
|
||||
|
||||
import com.bpgroup.poc.admin.app.login.exception.AdministratorNotFoundException;
|
||||
import com.bpgroup.poc.admin.app.login.exception.DoNotHaveAnyMenuException;
|
||||
import com.bpgroup.poc.admin.app.login.exception.InvalidPasswordException;
|
||||
import com.bpgroup.poc.admin.security.authentication.exception.AdministratorNotFoundException;
|
||||
import com.bpgroup.poc.admin.security.authentication.exception.DoNotHaveAnyMenuException;
|
||||
import com.bpgroup.poc.admin.security.authentication.exception.InvalidPasswordException;
|
||||
import com.bpgroup.poc.admin.domain.admin.entity.Administrator;
|
||||
import com.bpgroup.poc.admin.domain.admin.entity.AdministratorRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
|
@ -17,21 +17,20 @@ import java.util.stream.Collectors;
|
|||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional
|
||||
public class LoginService {
|
||||
|
||||
private final AdministratorRepository loginRepository;
|
||||
private final AdministratorRepository administratorRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
public LoginResult login(String loginId, String pwd) throws AdministratorNotFoundException, InvalidPasswordException, DoNotHaveAnyMenuException {
|
||||
|
||||
Optional<Administrator> administrator = loginRepository.findByLoginId(loginId);
|
||||
@Transactional
|
||||
public LoginResult login(String username, String password) throws AdministratorNotFoundException, InvalidPasswordException, DoNotHaveAnyMenuException {
|
||||
Optional<Administrator> administrator = administratorRepository.findByLoginId(username);
|
||||
if (administrator.isEmpty()) {
|
||||
throw new AdministratorNotFoundException(loginId);
|
||||
throw new AdministratorNotFoundException(username);
|
||||
}
|
||||
|
||||
if (!passwordEncoder.matches(pwd, administrator.get().getPassword())) {
|
||||
throw new InvalidPasswordException(loginId);
|
||||
if (!passwordEncoder.matches(password, administrator.get().getPassword())) {
|
||||
throw new InvalidPasswordException(username);
|
||||
}
|
||||
|
||||
return LoginResult.of(
|
||||
|
|
@ -43,7 +42,7 @@ public class LoginService {
|
|||
);
|
||||
}
|
||||
|
||||
private static LinkedHashSet<LoginResult.MenuInfo> getMenus(Administrator administrator) throws DoNotHaveAnyMenuException {
|
||||
private LinkedHashSet<LoginResult.MenuInfo> getMenus(Administrator administrator) throws DoNotHaveAnyMenuException {
|
||||
try {
|
||||
return administrator.getAdministratorRole().getRole().getRoleMenus().stream()
|
||||
.map(roleMenu -> LoginResult.MenuInfo.of(
|
||||
|
|
@ -65,4 +64,5 @@ public class LoginService {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.bpgroup.poc.admin.app.login.exception;
|
||||
package com.bpgroup.poc.admin.security.authentication.exception;
|
||||
|
||||
public class AdministratorNotFoundException extends Exception {
|
||||
public AdministratorNotFoundException(String message) {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.bpgroup.poc.admin.security.authentication;
|
||||
package com.bpgroup.poc.admin.security.authentication.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.bpgroup.poc.admin.security.authentication.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum AuthenticationFailReason {
|
||||
WRONG_LOGIN_ID("아이디 및 패스워드를 확인하세요."),
|
||||
WRONG_PASSWORD("아이디 및 패스워드를 확인하세요."),
|
||||
HAVE_NO_MENU("등록된 메뉴 권한이 없습니다. \n메뉴 등록 후 사용하시기 바랍니다."),
|
||||
INTERNAL_ERROR("서버 내부 오류가 발생했습니다.");
|
||||
|
||||
private final String message;
|
||||
|
||||
public static AuthenticationFailReason from(Exception e) {
|
||||
if (e instanceof AdministratorNotFoundException) {
|
||||
return WRONG_LOGIN_ID;
|
||||
} else if (e instanceof InvalidPasswordException) {
|
||||
return WRONG_PASSWORD;
|
||||
} else if (e instanceof DoNotHaveAnyMenuException) {
|
||||
return HAVE_NO_MENU;
|
||||
} else {
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.bpgroup.poc.admin.app.login.exception;
|
||||
package com.bpgroup.poc.admin.security.authentication.exception;
|
||||
|
||||
public class DoNotHaveAnyMenuException extends Exception {
|
||||
public DoNotHaveAnyMenuException() {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.bpgroup.poc.admin.app.login.exception;
|
||||
package com.bpgroup.poc.admin.security.authentication.exception;
|
||||
|
||||
public class InvalidPasswordException extends Exception {
|
||||
public InvalidPasswordException(String message) {
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
package com.bpgroup.poc.admin.values;
|
||||
|
||||
public class AdministratorMenu {
|
||||
}
|
||||
|
|
@ -1,34 +1,16 @@
|
|||
package com.bpgroup.poc.admin.web.login;
|
||||
|
||||
import com.bpgroup.poc.admin.security.authentication.AuthenticationFailReason;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/login")
|
||||
public class LoginController {
|
||||
|
||||
@GetMapping
|
||||
public String loginPage(
|
||||
@RequestParam(required = false) AuthenticationFailReason error,
|
||||
Model model
|
||||
) {
|
||||
if (error != null) {
|
||||
model.addAttribute("errorMessage", getMessage(error));
|
||||
}
|
||||
|
||||
public String loginPage() {
|
||||
return "login/login";
|
||||
}
|
||||
|
||||
private String getMessage(AuthenticationFailReason error) {
|
||||
return switch (error) {
|
||||
case WRONG_LOGIN_ID, WRONG_PASSWORD -> "아이디 또는 비밀번호가 일치하지 않습니다.";
|
||||
case HAVE_NO_MENU -> "등록된 메뉴가 없습니다.\n 메뉴 등록 후 이용해주세요.";
|
||||
default -> "서버에 오류가 발생했습니다.";
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
<script type="text/javascript" th:src="@{/js/pagehelper.js}"></script>
|
||||
<script type="text/javascript" th:src="@{/js/eventrouter.js}"></script>
|
||||
<script type="text/javascript" th:src="@{/js/httpinterceptor.js}"></script>
|
||||
<script type="text/javascript" th:src="@{/js/reqhelper.js}"></script>
|
||||
|
||||
<th:block th:replace="~{fragment/csrf/csrf :: applyCsrf}"></th:block>
|
||||
</head>
|
||||
|
|
@ -30,10 +31,24 @@
|
|||
</p>
|
||||
</form>
|
||||
<button type="button" id="loginButton" class="btn_confirm btn_login">로그인</button>
|
||||
<button type="button" id="loginJson" class="btn_confirm btn_login">로그인(JSON)</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" th:inline="javascript">
|
||||
document.getElementById('loginJson').addEventListener(('click'), function () {
|
||||
Reqhelper.reqPostJson('/login', {
|
||||
username: document.querySelector('input[name="loginId"]').value,
|
||||
password: document.querySelector('input[name="password"]').value
|
||||
}, function (res) {
|
||||
if (res.resultCode === '0000') {
|
||||
location.href = '/main';
|
||||
} else {
|
||||
PageHelper.showErrorModal(res.resultMessage);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const errorMessage = /*[[${errorMessage}]]*/ '';
|
||||
|
||||
if (errorMessage) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue