티스토리 뷰

ios 앱 심사 덕분에 애플 로그인을 개발하게 됐다. ( 구글 로그인은 있는데, 애플 로그인이 없다면 심사 통과 불가 )

 

애플 로그인은 자바스크립트로 구현했다.

( apple login request -> successHandler -> ajax -> rest controller (db 작업 및 session 생성) -> view)

 

1. 스크립트 및 로그인 버튼 추가

<script type="text/javascript" src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script>

<div id="appleid-signin" data-mode="logo_only">
    <img src="이미지경로">
</div>

https://developer.apple.com/documentation/sign_in_with_apple/displaying_sign_in_with_apple_buttons_on_the_web

 

Apple Developer Documentation

 

developer.apple.com

https://appleid.apple.com/signinwithapple/button

 

https://appleid.apple.com/signinwithapple/button

 

appleid.apple.com

* 위 사이트에서 애플 로그인 버튼 css 설정 및 참고 가능

 

 


2. AppleID.auth.init, success 및 fail handler 호출

( 로그인 페이지 따로 호출 시 : https://appleid.apple.com/auth/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri})

 

<script>
(function() {
    AppleID.auth.init({
        clientId : app에서 지정한 clientId,
        scope : 'name email',
        redirectURI : app에서 지정한 redirect_uri,
        usePopup : true //true : 다른 창 호출, false : 같은 창 호출
    });
    
    document.addEventListener('AppleIDSignInOnSuccess', (data) => {
          var authorization = data.detail.authorization;
          var userName, userEmail;
          
          user = data.detail.user;
          userEmail = user.email;
          userName = user.name.lastName + user.name.firstName;
           
          var data = {
            'idToken' : authorization.id_token,
            'code' : authorization.code,
            'state' : authorization.state,
            'userName' : userName,
            'userEmail' : user.email,
          };

          $.ajax({
            url: "/rest/appleLoginCallback",
            type: "POST",
            dataType:"text",
            data: data,
            success: function(data){
              if(data == 'success'){
                window.location.href="/main";
              }else if(data == 'fail'){
                window.location.href="/login";
              }
            },
            error: function (error){
              console.log(error);
              alert('다시 시도하세요');
              window.location.href="/login";
            }
        });

      });

      document.addEventListener('AppleIDSignInOnFailure', (error) => {
          alert('로그인에 실패했습니다. 다시 시도하세요.');
      });

    }());
</script>


* usePopup 값에 따라 다른 점
   ture : success가 redirectURI로 지정된 페이지로 리턴 (name 값 안 넘어옴)
   false : 스크립트 핸들러로 리턴 (scope에 지정된 값 다 넘어옴)

 

 

 

: 로그인 시 나의 이메일 가리기가 있다. 안심번호랑 비슷하다고 생각하면 된다.

애플쪽에서 랜덤으로 이메일을 리턴해주는데 해당 메일로 메일 보내기가 가능하고, 개인 이메일 주소를 비공개로 유지할 수 있다.

 

 

AppleIDSignInOnSuccess return data

                                            * user 값은 최초 로그인 시에만 제공

 

 

3. rest controller 로그인 처리

@RequestMapping(value ="/rest/appleLoginCallback", method = RequestMethod.POST, produces = "application/json")
public String appleLoginCallback(@RequestParam Map<String, Object> bodyMap, HttpServletRequest request) throws Exception {

    String returnStr = "fail";
    String token = MapUtils.getString(bodyMap, "idToken");
    String userName = MapUtils.getString(bodyMap, "userName", "");

    String[] check = token.split("\\.");
    Base64.Decoder decoder = Base64.getDecoder();
    String payload = new String(decoder.decode(check[1]));

    ObjectMapper mapper = new ObjectMapper();
    Map<String, Object> tokenReturnMap = mapper.readValue(payload, Map.class);

    Map<String, Object> userMap = new HashMap<String, Object>();

    userMap.put("code", bodyMap.get("code"));
    userMap.put("memberId", tokenReturnMap.get("sub"));
    userMap.put("email", tokenReturnMap.get("email"));
    userMap.put("nickName", userName);
    userMap.put("loginType", "apple");

    boolean result = service.userInfo(userMap);

    if(result){
        UserDetails principal = detailService.loadUser((String)userMap.get("memberId"));
        Authentication authentication = new UsernamePasswordAuthenticationToken(principal, token, principal.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication); //시큐리티 강제 로그인
        HttpSession session = request.getSession();	//session 생성
        returnStr = "success";
    }
    return returnStr;
}

 

 

 

 

* 로컬에서 애플 로그인 테스트 시 app에 설정한 redirect uri로 도메인 변경 필요 ( hosts파일 )

  로컬은 redirect uri로 설정 불가, https 프로토콜만 설정 가능

  로컬에서 테스트 하기 위해 프로젝트에 ssl 적용. (localhost는 http가 기본)

 

 

 

'Development > JAVA' 카테고리의 다른 글

[JAVA] Http POST urlencoded  (0) 2022.04.11
[JAVA] json to int  (0) 2022.01.05
[JAVA] JWT decode  (0) 2021.11.10
[JAVA] Http POST urlencoded  (0) 2021.08.24
[JAVA] Bearer token Authorization  (0) 2021.08.22
댓글
링크
최근에 올라온 글
Total
Today
Yesterday