WIL

40주차 - 로그인 문제 해결

haedal-uni 2022. 6. 19. 21:46
728x90

문제점 해결

이전에 에러(모든 페이지에서 css, js 실행이 안되던 에러) 해결할 때보다 빨리 해결하게 되었다.

안되면 갈아엎으라는 교훈을 준덕에?

역시 에러를 확인하려면 한번 갈아엎어버리는 형식으로 가야하나보다.

 

그래도 완전히 갈아엎어서 처음부터 하나씩 작성하기보다 업그레이드해서 문제를 해결했다.

github를 활용해서 특정 커밋으로 돌아가 체크했는데 

$ git reset --hard (복사한 commit ID)

backend에 문제가 없다는 것을 알게 되었고 문제를 단기간에 해결하게 되었다.

[add] 로그인 성공 로직 작성 [#70] #72           

 

 

로그인 성공이 되지 않았던 것은 로그인 버튼 문제였다.

이 전에 github 커밋 로그를 통해 이전 코드를 체크하면서 실행했는데 문제가 없어서

front 문제인 것 같아 코드를 확인하다가 발견하게 되었다.

 

자체 새로고침을 막기위해서 type="button"을 설정한 것인데 

이것이 로그인을 막은 원인이었다.

 

 

⬇️ 현재 코드

<button class="btn" type="button" onclick="checkSignIn()">Get Started</button>

 

⬇️ 가장 최근 front 커밋 코드

<button class="btn" onclick="checkSignIn()">Get Started</button>

 

 

결과적으로 front 문제였다.

 

그래서 제대로 입력을 한 경우라면 type을 button이 아닌 submit로 바꿔주기로 했다.

* button의 기본 default 값이 submit

출처 : [HTML] HTML button 의 type 종류들 (submit/button/reset)

 

 

 

document.getElementById("signInBtn").setAttribute("type","submit");
document.getElementById("signInBtn").click()

출처 : [javascript - (30) ] input type 동적으로 변경하기

 

 

 

 

 

backend : [add] 로그인 성공 로직 작성 [#70] #72

front : [add] 로그인 성공 로직 작성 [#76] #78

 


로그인 예외 처리 2가지 방법 작성 정리

이 전에 예외처리를 하고 새로 커스터마이징을 작성해서 문제가 있다고 생각했었다.

그러나 CustomAuthFailureHandler 를 작성하고 활용하지 못했고 로그인을 실행한게 아니라

로그인 실패했을 때 로직을 작성한 거라서 아직 갈 길이 멀다.

2022.06.15 - [TIL] - 273일차(모험 182일차) - 로그인 예외 처리

 

새로고침의 여부에 따라 해당 코드가 실행 여부가 달라진 것이다.

 

 

 

아래 코드를 사용하려면 button type을 submit로 작성해야한다.

SecurityConfig에서 failureHandler에 등록 후 Controller에서 errorMsg를 출력하는

코드를 작성하고 사용을 하지는 않았다.

.failureHandler(customFailureHandler)

 

@GetMapping("/user/login/error")
public Model loginError(@RequestParam(value = "error", required = false) String error,
                        @RequestParam(value = "exception", required = false)
                                String exception, Model model) {
    model.addAttribute("error", error);
    model.addAttribute("exception", exception);

    return model;
}

 

 

그리고 해당 url을 받아오는 방법으로 진행하면 된다.

const searchParams = new URLSearchParams(location.search);

for (const param of searchParams) {
    console.log(param);
}

출처 : [JS] URL parameter 가져오기

 

 

 

 

원래 사용하던 방법은 버튼 타입이 button으로써

js에서 먼저 input에 빈 값이 있는지 체크 한 후 빈 값이 없는 경우에 해당 값을 controller에 보낸다. 

service에서 값이 있는지 비밀번호는 맞는지 체크하며 각각의 경우에 따른 return값을 보낸다.

그 값을 js에서 띄우는데 로그인 성공인 경우에는

(위에서 작성한 부분 _ 문제점 해결 title에서 작성한 방식)

button 타입을 submit으로 바꿔주고 로그인을 시도하는 로직이다.

 

나는 새로고침이 싫어서 기존에 계속 사용했던 방법(type = "button")으로 하고 있다.

혹시 위의 방법을 사용하게 될 수도 있을 것 같아서 정리해봤다.

* submit에 작성된 코드는 button 에 작성하는 코드에는 상관없는 코드이므로 삭제 가능

button에서 작성한 코드 또한 submit에서 작성한 코드에는 상관없으므로 삭제해도 됨

 


type = "button"으로 사용할 경우

<button class="btn" type="button" onclick="checkSignIn()">Get Started</button>

 

LoginController(@RestController)

// 로그인 페이지
@PostMapping("/user/login/input")
public String login(@ModelAttribute LoginDto loginDto) {
    return userService.login(loginDto);
}

 

UserService

// 로그인 페이지
public String login(LoginDto loginDto) {
    String username = loginDto.getUsername();
    String password = loginDto.getPassword();

    // id 찾기
    Optional<User> foundId = userRepository.findByUsername(username);

    //pw 찾기
    Optional<User> foundPw = userRepository.findAllByUsername(username);

    if (foundId.isPresent()) {
        String encodedPw = foundPw.get().getPassword();

        if (passwordEncoder.matches(password, encodedPw) && (!password.equals(encodedPw))) {
            return "환영합니다.";
        } else {
            return "비밀번호를 잘 못 입력하셨습니다.";
        }
    } else {
        return "등록된 사용자가 없습니다.";
    }

}

 

login.js

success: function (response) {
    if (response == "환영합니다.") {
        $(".LoginSuccessMsg").text(username + "님" + " " + response);
        setTimeout(function () {
            document.getElementById("signInBtn").setAttribute("type","submit");
            document.getElementById("signInBtn").click()
            // <button className="btn" type="submit" onClick="checkSignIn()">Get Started</button>
        }, 1500)
    } else {
        $(".Login-danger").text(response)
    }

}

 


type = "submit"로 사용할 경우

<button class="btn" type="submit" onclick="checkSignIn()">Get Started</button>

 

UserController (@Controller)

@GetMapping("/user/login/error")
public Model loginError(@RequestParam(value = "error", required = false) String error,
                        @RequestParam(value = "exception", required = false)
                                String exception, Model model) {
    model.addAttribute("error", error);
    model.addAttribute("exception", exception);

    return model;
}

 

 

webSecurityConfig

private final AuthenticationFailureHandler customFailureHandler;
                .and()
                .formLogin()
                .loginPage("/user/login")
                .failureHandler(customFailureHandler) // 추가

 

 

CustomAuthFailureHandler

@Component
public class CustomAuthFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
            throws IOException, ServletException {
        String errorMessage;
        if (exception instanceof BadCredentialsException) {
            errorMessage = "아이디 또는 비밀번호가 맞지 않습니다. 다시 확인해 주세요.";
        } else if (exception instanceof InternalAuthenticationServiceException) {
            errorMessage = "내부적으로 발생한 시스템 문제로 인해 요청을 처리할 수 없습니다. 관리자에게 문의하세요.";
        } else if (exception instanceof UsernameNotFoundException) {
            errorMessage = "계정이 존재하지 않습니다. 회원가입 진행 후 로그인 해주세요.";
        } else if (exception instanceof AuthenticationCredentialsNotFoundException) {
            errorMessage = "인증 요청이 거부되었습니다. 관리자에게 문의하세요.";
        } else {
            errorMessage = "알 수 없는 이유로 로그인에 실패하였습니다 관리자에게 문의하세요.";
        }
        errorMessage = URLEncoder.encode(errorMessage, "UTF-8");
        setDefaultFailureUrl("/user/login?error=true&exception=" + errorMessage);
        super.onAuthenticationFailure(request, response, exception);
    }
}

 

 

login.js ( url 받아오기 )

const searchParams = new URLSearchParams(location.search);

for (const param of searchParams) {
    console.log(param);
}

 

 

728x90

'WIL' 카테고리의 다른 글

42주차 - 프로젝트  (0) 2022.07.03
41주차 - 프로젝트 구현 코드 정리  (0) 2022.06.26
39주차 - 회원가입  (0) 2022.06.12
38주차 - 프로젝트 front  (0) 2022.06.05
37주차 - 프로젝트  (0) 2022.05.29