로그인 기능 구현 2 : 네아로(네이버아이디로그인) api 사용하기 - 스프링, jsp, 오라클, mybatis

2024. 3. 23. 21:26카테고리 없음

이번에는 "네이버 로그인 api" 를 사용하는 포스팅이다. 

 

https://developers.naver.com/docs/login/api/api.md

여기에 설명되어 있는 것을 참조해서 진행하였다. 그리고, 자바스크립트로 구현하는 방식을 택하였다. 

 

1단계 : 시작은, 위에 보이는 이미지의 네이버 로그인 버튼을 만드는 것에서부터 시작한다. 

네이버 로고를 만들고, 버튼을 만드는 작업이 필요한 게 아니라, api documnet 에 제시된 대로, 

    <!doctype html>
    <html lang="ko">
    <head>
    <meta charset="utf-8">
    <title>네이버 로그인</title>
    <script type="text/javascript" src="https://static.nid.naver.com/js/naverLogin_implicit-1.0.3.js" charset="utf-8"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
    </head>
    <body>
    <!-- 네이버 로그인 버튼 노출 영역 -->
    <div id="naver_id_login"></div>
    <!-- //네이버 로그인 버튼 노출 영역 -->
    <script type="text/javascript">
        var naver_id_login = new naver_id_login("YOUR_CLIENT_ID", "YOUR_CALLBACK_URL");
        var state = naver_id_login.getUniqState();
        naver_id_login.setButton("white", 2,40);
        naver_id_login.setDomain("YOUR_SERVICE_URL");
        naver_id_login.setState(state);
        naver_id_login.setPopup();
        naver_id_login.init_naver_id_login();
    </script>
    </html>

이 부분을 내 jsp 파일에 넣었다. 여기서, 사용자마다 달라야 하는 부분은, 3군데이다. 

YOUR_CLIENT_ID , YOUR_CALLBACK_URL, YOUR_SERVICE_URL 이렇게 3군데 이다. 

 

YOUR_CLIENT_ID 에는 네이버에 로그인하고, 내 애플리케이션을 등록하면, 네이버에서 발급하는 Client ID 를 써주면 된다. 

아래 이미지에서 빨강부분에 적혀있는 것을 말한다.

그리고, YOUR_CALLBACK_URL 은 뭐냐면, 사용자가 네이버에 로그인하면, 네이버가 사용자에 대한 정보를 다시 돌려주는데, 그 정보를 받을 컨트롤러의 url을 써주면 된다. 나는 "http://localhost:8080/naver-callback" 이라고 써주었다. YOUR_CALLBACK_URL 에 대한 이해가 덜 된다면 포스팅을 읽다보면 이해가 갈거라고 확신한다. 

마지막으로, YOUR_SERVICE_URL 에는 내 웹애플리케이션의 도메인을 써주면 된다. 

내 프로젝트는 아직 배포하지 않았기 때문에, "http://localhost:8080" 이라고 써주었다. 

그래서 위 버튼을 누르면 어떻게 되는가? 

아래 페이지가 나오게 된다.

여기서 사용자가 자신의 회원정보를 입력하게 되면, 아까 설정해줬던, YOUR_CALLBACK_URL 에 써줬던 url(나는 "http://localhost:8080/naver-callback" 라고 써줬다고 했지.) 로 네이버 서버가 HTTP 메세지를 보내주게 된다.

 

그 HTTP 메세지를 받는 컨트롤러를 만들어줘야 한다. 아래와 같이 생겼다. 

2단계 : 네이버 서버가 보내준 데이터를 받는 컨트롤러 만들기

@Slf4j
@Controller
@RequiredArgsConstructor
public class NaverLoginController {

    @GetMapping("/naver-callback")
    public String naverController(){
        return "/login/naverLogin";
    }

}

이 컨트롤러에서는 아무것도 안해줬고, 바로 naverLogin.jsp 로 이동시켰다. 

 

3단계 : naverLogin.jsp

naverLogin.jsp 는 https://developers.naver.com/docs/login/api/api.md 여기에서 callback.html 이라고 했던 부분을 보고 만들었다. 안내되어 있는 callback.html 은 아래와 같이 되어 있다. 

<!doctype html>
<html lang="ko">
<head>
<script type="text/javascript" src="https://static.nid.naver.com/js/naverLogin_implicit-1.0.3.js" charset="utf-8"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>
<script type="text/javascript">
  var naver_id_login = new naver_id_login("YOUR_CLIENT_ID", "YOUR_CALLBACK_URL");
  // 접근 토큰 값 출력
  alert(naver_id_login.oauthParams.access_token);
  // 네이버 사용자 프로필 조회
  naver_id_login.get_naver_userprofile("naverSignInCallback()");
  // 네이버 사용자 프로필 조회 이후 프로필 정보를 처리할 callback function
  function naverSignInCallback() {
    alert(naver_id_login.getProfileData('email'));
    alert(naver_id_login.getProfileData('nickname'));
    alert(naver_id_login.getProfileData('age'));
  }
</script>
</body>
</html>

그대로 써놓고, 테스트를 해보니, alert 창이 3개 띄워졌는데, 그게 로그인한 내 네이버계정에 담겨있던, email(wowns590@naver.com), nickname(별명공개는.. 좀.. 그래서 뭐 예를 들어, 바보 라고 표현하겠습니다), age(나이) 가 담긴 alert창 3개였다. 

그래서, 나는 아래와 같이, 받을 수 있는 데이터 중에 쓸만한 것들을 받아서 fetch 를 이용해서 /make-account 라는 url 로 post 요청을 보냈다.

naverLogin.jsp 의 전체 코드는 아래와 같다. 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:import url="/jsp/bootstrapconfig/index.jsp"/>


<html>
<head>
    <!-- naver 로그인 관련 -->
    <script type="text/javascript" src="https://static.nid.naver.com/js/naverLogin_implicit-1.0.3.js" charset="utf-8"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>



<script type="text/javascript">
  var naver_id_login = new naver_id_login("akLY3ixqz148IBJVFcFD", "http://localhost:8080/naver-callback");
  // 네이버 사용자 프로필 조회
  naver_id_login.get_naver_userprofile("naverSignInCallback()");
  // 네이버 사용자 프로필 조회 이후 프로필 정보를 처리할 callback function
  function naverSignInCallback() {
    let name = naver_id_login.getProfileData('name');
    let email = naver_id_login.getProfileData('email');
    let id = naver_id_login.getProfileData('id');

    fetch('/make-account', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        'name': name,
        'email': email,
        'id' : id,
      }),
    })
    .then(response => {
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      return response.text();
    })
    .then(data => {
        if(data == 'createAccount' || data == 'alreadyExistsByNaver'){
          window.location.href = '/';
        } else if (data == 'alreadyExistByWordCharger') {
          alert('회원가입 이력이 확인되었습니다. 해당 아이디로 로그인해주세요.');
          window.location.href = '/login-form';
        }
    })
    .catch(error => console.error('There has been a problem with your fetch operation:', error));


  }
</script>



</body>
</html>

현재 나는 name email id 얻어온 다음, 그 데이터들을 fetch 로 post 요청을 보내고 있는데, 

이외에도 다양한 데이터를 받을 수 있다. 

그리고 fetch 문의 .then 구문에서 받아온 문자열이 무엇인지에 따라, 다른 처리를 하고 있는데, 이는 아래 있는 fetch 로 보낸 post 요청을 받는 컨트롤러인 /make-account 라는 url 을 매핑하는 컨트롤러에 대해 이해해야 이해가 될 것이다. 

 

4단계. make-account 라는 url 을 매핑하는 컨트롤러

@PostMapping("/make-account")
    @ResponseBody
    public String makeAccount(@RequestBody NaverServerSendMeDataDTO naverServerSendMeDataDTO, HttpServletRequest request) {
        String name = naverServerSendMeDataDTO.getName();
        String email = naverServerSendMeDataDTO.getEmail();
        String id = naverServerSendMeDataDTO.getId();

        // 회원가입한 적이 있는가?
        // 이를 판단하기 위해서는 네이버 서버가 준 데이터 중 이메일 부분을 가지고 내 db 테이블 중 email 테이블에 일치하는 행이 있다면
        // 가입한 이력이 있는 회원이라고 판단할 것이다.
        // 그런데, 밑에서 보면 알겠지만, 네이버로그인을 함으로써 자동으로 회원가입되는 경우에는 email 테이블의 행이 안들어가기 때문에,
        // 이메일만으로는 회원가입이력이 있는지 여부를 판단하기에 부족하다.
        // 네이버로 로그인함으로써 자동회원가입한 경우를 판단하기 위해서, 네이버로 로그인함으로써 자동회원가입할 때에,
        // member 테이블의 user_id 컬럼값을 "nv_" + email의 앞부분 으로 하기로 했기 때문에,
        // member 테이블에서 user_id 컬럼값이 "nv_" + email 앞부분인 행이 없는 경우에야
        // 비로소, 회원가입이력이 없다고 판단할 것이다.

        // naver 서버가 준 데이터 중 email 값은 지금 "wowns590@naver.com" 이렇게 들어와있는데,
        // 내 email 테이블에는 email 컬럼으로 wowns590 이렇게만 들어가도록 설계했기 때문에,
        // 지금 email 변수에 들어있는 값을 @ 를 기준으로 앞에 부분인 wowns590 만 잘라서
        // email 테이블의 email 컬럼과 비교를 진행해야 한다.

        int atIndex = email.indexOf("@"); // wowns590@naver.com 이라는 문자열에서 @가 몇번째 위치해있는지 확인.
        String emailFragment = email.substring(0, atIndex); // substring 을 이용해서 잘라냄.
        String domain = email.substring(atIndex + 1); // @는 제외한 @ 뒤의 부분을 얻기 위해 atIndex에 1을 더함
        String beId = "nv_" + emailFragment; // 밑에 코드에 여러군데에서 사용됨.

        // email 테이블에서 email 컬럼값이,
        // emailFragment 이라는 변수와 동일한 행을 조회한다.
        EmailDTO emailDTO = emailMapper.emailCountByEmail(emailFragment);

        boolean flag = false;

        if (emailDTO != null) { // 만약 조회된 행이 있다면, 그 행의 domain 컬럼 값이 domain 변수와 동일한지 체크하고,
                                // domain 컬럼까지 동일하다면, flag 를 true 로 바꾸도록 함.
            if(emailDTO.getDomain().equals(domain)){
                flag = true;
            }
        }

        MemberJoinDTO member = memberMapper.findMemberById(beId);
        if (member != null) { // 만약 네이버로 로그인함으로써 자동으로 회원가입된 경우, flag 가 true가 되도록 함.
            flag = true;
        }

        // 일단, flag 의 값이 true 인지 false 인지에 따라 나눠야 한다.
        // flag 값이 여전히 false 라면,
        // 우리 웹사이트에 직접 회원가입을 하지도 않았고, 네이버로 로그인해서 자동으로 회원가입된적도 없다는 의미거든?
        // 그렇다면, 그냥 네이버서버가 준 데이터로 회원가입을 진행하면 된다.
        // 이때, db 중 naver_member 라는 테이블에도 행을 추가해줘야 한다. <- 용도는 뒤에 설명되어 있다.
        // 이 테이블의 컬럼 중 핵심은
        // 네이버 서버가 네이버 계정마다 부여한 고유한 키인 현재 id 라는 변수에 담겨있는 값을
        // 넣은 컬럼인 naver_id 라는 이름의 컬럼이다.

        if (flag == false) {
            // member 테이블에 행 넣기.
            Integer sequence = memberMapper.selectNextSequenceValue(); // id 컬럼 값
            String password = id; // password 컬럼 값 : 네이버서버가 네이버계정마다 부여한 고유한 값
            String userName = name; // user_name 컬럼 값 : 네이버서버가 준 데이터 중 name 값
            memberMapper.insertMember(sequence, beId, id, name); // 삽입.

            // naver_member 테이블에도 행을 넣을 것이다.
            // naver_member 테이블에는 총 3개의 컬럼이 있다.
            // id : pk 로서, 시퀀스값을 넣어줄 컬럼.
            // member_id : 방금 member 테이블에 insert 쿼리 실행할 때 썻던 member 테이블의 id 컬럼(pk) 값을 참조하는 외래키로 설정.
            // naver_id : 네이버 서버가 네이버계정마다 부여한 고유한 값을 담을 컬럼.
            Integer nextSequenceValue = naverMemberMapper.selectNextSequenceValue(); // id 컬럼 값
            naverMemberMapper.insertRow(nextSequenceValue, sequence, id);

            //세션 설정
            MemberJoinDTO findedMember = memberMapper.findMemberById(beId);
            HttpSession session = request.getSession(true);
            session.setAttribute("loginedMember", findedMember);

            return "createAccount";
        } else{
            // flag 가 true 라면,
            // 우리 웹사이트에 직접 회원가입을 했든, 혹은 네이버로 로그인함으로써 자동으로 회원가입을 했든
            // 우리 웹사이트에 회원이라는 소리이다.

            // 이 경우 2가지로 분류해야 한다.
            // 1. 우리 웹사이트에 직접 회원가입을 한 경우.
            // 2. 네이버로 로그인함으로써 자동으로 회원가입을 한 경우.

            // 1번인지 2번인지는 어떻게 판단할 것인가?
            // 네이버가 네이버계정마다 부여한 고유한 값으로 db 테이블 중 naver_member 라는 테이블에서
            // 행을 조회한다. 만약, 조회된 행의 개수가 0이면, 우리 웹사이트에 직접 회원가입을 한 경우이고,
            // 1이상이면 네이버로 로그인함으로써 자동으로 회원가입된 경우라고 판단할 수 있다.

            // 1. 우리 웹사이트에 직접 회원가입을 한 경우 에는 새로운 계정을 만들지 않는다.
            // 그리고, alreadyExistByWordCharger 라는 문자열을 되돌려 줄것이다.
            // 그러면, fetch 구문에서 alreadyExistByWordCharger 라는 값이 온 경우,
            // alert('회원가입한 이력이 확인되었습니다. 그 아이디로 로그인해주세요.') 라고 띄워주고, loginForm.jsp 이 보여지도록 할 것.

            // 2. 네이버로 로그인함으로써 자동으로 회원가입을 한 경우 에는
            // 세션 설정을 해주고, alreadyExistsByNaver 라는 문자열을 되돌려 줄것이다.
            // 그러면, fetch 구문에서 alreadyExistsByNaver 라는 값이 온 경우,
            // window.location.href="" 를 이용해서 / 라는 url 을 매핑하는 컨트롤러로 get 요청을 하게 할 것이다.

            Integer rowCount = naverMemberMapper.rowCount(id);
            if (rowCount == 0) {
                // 1. 우리 웹사이트에 직접 회원가입을 한 경우.
                return "alreadyExistByWordCharger";

            } else{
                // 2. 네이버로 로그인함으로써 자동으로 회원가입을 한 경우, 세션 설정.
                MemberJoinDTO findedMember = memberMapper.findMemberById(beId); //네이버로 로그인함으로써 자동으로 회원가입할 때, user_id 컬럼값으로 beId 변수를 썻기 때문에 beId를 통해 memeber 테이블의 행을 조회함.
                HttpSession session = request.getSession(true);
                session.setAttribute("loginedMember", findedMember);

                // alreadyExistsByNaver 리턴.
                return "alreadyExistsByNaver";

            }

        }
    }

 

대단히 복잡해보이지만, 큰 흐름만 파악한다면 그리 복잡하지도 않다. 큰 흐름은 아래와 같다. 

1. 회원가입한 이력이 있는가?

2. 없다면 -> 네이버서버가 보내준 데이터를 가지고 간단하게 회원가입을 진행해버린다. 

    있다면 -> 3. 으로

3. 만약 내 홈페이지에서 직접 정보를 입력해서 회원가입한 경우에는 "회원가입한 이력이 있으니 그 아이디로 로그인해달라고 안내한다"

만약 네이버 아이디로 로그인함으로써 회원가입이 자동으로 진행된 경우에는 "세션을 설정해주고 / 으로 get 요청보내서 사용자에게 네이버아이디로 로그인한듯한 효과를 느끼도록 해준다"

 

회원가입한 이력이 있는 경우, 왜 사용자에게 원래 내 홈페이지에서 필요한 다른 정보(이메일, 주소 등) 을 더 입력받아서 완벽한 계정을 만들도록 하지 않았는가? 그건 https://developers.naver.com/docs/login/devguide/devguide.md 이 글의 의견에 동의했기 때문이다. 

 

이제 다시 naverLogin.jsp 의 fetch 구문 중 then 구문을 보면, 이해가 될 것이다.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:import url="/jsp/bootstrapconfig/index.jsp"/>


<html>
<head>
    <!-- naver 로그인 관련 -->
    <script type="text/javascript" src="https://static.nid.naver.com/js/naverLogin_implicit-1.0.3.js" charset="utf-8"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>



<script type="text/javascript">
  var naver_id_login = new naver_id_login("akLY3ixqz148IBJVFcFD", "http://localhost:8080/naver-callback");
  // 네이버 사용자 프로필 조회
  naver_id_login.get_naver_userprofile("naverSignInCallback()");
  // 네이버 사용자 프로필 조회 이후 프로필 정보를 처리할 callback function
  function naverSignInCallback() {
    let name = naver_id_login.getProfileData('name');
    let email = naver_id_login.getProfileData('email');
    let id = naver_id_login.getProfileData('id');

    fetch('/make-account', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        'name': name,
        'email': email,
        'id' : id,
      }),
    })
    .then(response => {
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      return response.text();
    })
    .then(data => {
        if(data == 'createAccount' || data == 'alreadyExistsByNaver'){
          window.location.href = '/';
        } else if (data == 'alreadyExistByWordCharger') {
          alert('회원가입 이력이 확인되었습니다. 해당 아이디로 로그인해주세요.');
          window.location.href = '/login-form';
        }
    })
    .catch(error => console.error('There has been a problem with your fetch operation:', error));


  }
</script>



</body>
</html>

그리고, 로그인 기능 구현 1 에서 나왔었는데,

localhost:8080/ 이라는 url 을 매핑하는 컨트롤러는 HTTP요청을 보낸 그 사용자와 연결된 session 객체에 loginedMember 라는 키를 가진 데이터가 있는 경우에만 loginedHome.jsp 파일로 이동시키는 컨트롤러였다.

그리고 localhost:8080/login-form 이라는 url을 매핑하는 컨트롤러는 단순히 loginForm.jsp 파일로 이동시키는 컨트롤러였다.

 

참고로, loginedHome.jsp 는 아래와 같이 생겼고, 

 

loginForm.jsp 는 아래와 같이 생겼다.

 

그런데, 지금 보면, 사용자가 직접 내 프로젝트에서 정보를 입력하여 회원가입한 이력이 있는 경우, 네이버서버가 준 데이터로 회원가입을 진행시키지 않고, 사용자에게 회원가입이력이 있으니 그 아이디로 로그인하라고 안내하고 있는데, 왜 그렇게 했는가? 

만약에, 직접 정보를 입력하여 회원가입하고 결제를 진행했다고 가정해보자. 다음에 그 회원이 로그인할 때 회원가입을 진행했었는지 아니면 네이버 로그인으로 대체했는지 기억못하고, 결제했는지도 기억못하는 경우라고 가정해보자. 

근데, 이번에는 네이버로그인으로 로그인을 진행했다고 해보자. 만약 이때 "회원가입한 이력이 있으니 그 아이디로 로그인하라" 는 안내를 하지 않고 그냥 새로운 계정을 하나 더 만들게 된다면, 사용자는 자신이 결제한지도 기억못하기 때문에 또 결제를 진행하게 될 위험이 있다. 

그래서, 직접 정보를 입력하여 회원가입한 이력이 있는 경우, 네이버 로그인으로 회원가입을 진행시키지 않고 "회원가입한 이력이 있으니 그 아이디로 로그인하라" 라고 안내하도록 설계하였다. 

 

그렇다면, 반대로 네이버로그인으로 회원가입이 된 사용자인데, 직접 정보를 입력하여 회원가입하려는 경우에도 "네이버 로그인으로 회원계정이 생성되었으니, 네이버 로그인으로 로그인해달라" 라고 안내해줘야 하겠지. 

그래서 아래와 같이 직접 정보를 입력하여 회원가입하는 컨트롤러에서 이를 처리하였다. 

    @PostMapping("/Join-form")
    public String postJoinFormControllerMethod (@Valid @ModelAttribute MemberJoinDTO memberJoinDTO, BindingResult bindingResult){
        //유효성 검사
        if (memberJoinDTO.getUserId().equals("") ) {
            bindingResult.rejectValue("userId", null,"아이디를 입력 해주세요");
        }
        if (memberJoinDTO.getPassword().equals("")) {
            bindingResult.rejectValue("password", null, "비밀번호를 입력해주세요");
        }
        if (memberJoinDTO.getUserName().equals("")) {
            bindingResult.rejectValue("userName", null, "이름을 입력해주세요");
        }

        if (memberJoinDTO.getZipCode().equals("")|| memberJoinDTO.getStreetAddress().equals("")|| memberJoinDTO.getAddress().equals("")) {
            bindingResult.rejectValue("zipCode", null, "우편번호를 찾기를 통해 주소를 찾아주세요.");
        }
        if (memberJoinDTO.getPhoneNumberStart().equals("") || memberJoinDTO.getPhoneNumberMiddle().equals("") || memberJoinDTO.getPhoneNumberEnd().equals("")) {
            bindingResult.rejectValue("phoneNumberStart", null, "전화번호를 입력해주세요");
        }

        if (bindingResult.hasErrors()) {
            log.info("bindingResult = {}", bindingResult);
            return "/login/joinForm";
        }

        String email = memberJoinDTO.getEmail();
        MemberJoinDTO findMember = memberMapper.findMemberById("nv_" + email);

        if (findMember != null) {
            return "redirect:/login-form?goToNaverLogin=goToNaverLogin";
        }

        //checkbox value : on => 1 , null => 0  변환
        MemberJoinDTO changedMemberJoinDTO = joinService.onAndNullChange(memberJoinDTO);

        // 비밀번호 해싱
        String rawPassword = changedMemberJoinDTO.getPassword();
        String encodedPassword = passwordEncoder.encode(rawPassword);
        changedMemberJoinDTO.setPassword(encodedPassword);

        //insert 진행 서비스
        insertMemberService.insertMember(changedMemberJoinDTO);
        return "/home/home";
    }

 

 

        String email = memberJoinDTO.getEmail();
        MemberJoinDTO findMember = memberMapper.findMemberById("nv_" + email);

        if (findMember != null) {
            return "redirect:/login-form?goToNaverLogin=goToNaverLogin";
        }

이 부분인데, 네이버로 로그인해서 계정이 생성되는 경우에는 member 테이블의 user_id 컬럼 값으로 "nv_" + 이메일의 앞부분 이 들어가기 때문에, 이를 이용해서 만약 member 테이블에 "nv_" + 사용자가 직접 회원가입을 진행하면서 입력한 이메일 을 user_id 컬럼의 값으로 하는 행이 존재한다면, /login-form 으로 리다이렉트하도록 하면서 쿼리스트링으로 goToNaverLogin=goToNaverLogin 이라는 데이터를 담아주었다. 

 

그리고, /login-form 이라는 get요청(HTTP요청)을 받는 컨트롤러도 아래와 같이 좀 수정했다. 

    @GetMapping("/login-form")
    public String getLoginFormControllerMethod(Model model, @RequestParam(required = false) String goToNaverLogin) {
        if (goToNaverLogin != null) {
            model.addAttribute("goToNaverLogin", goToNaverLogin);
        }
        model.addAttribute("loginDTO", new LoginDTO());
        return "/login/loginForm";
    }

만약, goToNaverLogin 이라는 키로 쿼리스트링이 온 경우, model 에 goToNaverLogin 라는 키로 데이터가 담기도록 해주었다. 

그리고 이 컨트롤러로 인해 이동되는  loginForm.jsp 파일에서  아래와 같은 코드를 두어, 만약 model 에 goToNaverLogin 이라는 키를 가진 데이터가 담겨져 있다면, "네이버로그인으로 생성된 계정이 확인되었습니다. 네이버로 로그인 해주세요." 라는 텍스트를 담은 alert창을 띄워주도록 하였다. 

<c:if test="${not empty goToNaverLogin}">
<script>
alert('네이버로그인으로 생성된 계정이 확인되었습니다. 네이버로 로그인 해주세요.');
</script>
</c:if>

 

 

끝.