본문 바로가기
개발 지식/정리

Spring OAuth2.0 카카오 로그인 Spring + react(next.js)

by 꾸준함 2023. 4. 7.

Oauth Login (kakao) 백(Spring)+프론트(Next.js)

Back(Spring)이랑 Front(next.js)를 통해 카카오 로그인을 구현하였습니다.

1. 순서

  1. Front(next.js)에서 javasript key를 통해 kakao api호출 ( code 받아오기 )
  2. 받아온 code를 backend에 요청해서 accessToken이나 사용자의 정보등을 받아오기

백엔드 [Backend] ( Spring )

1.Gradle Dependency 추가

implementation group: 'org.springframework.security', name: 'spring-security-oauth2-client', version: '5.6.3'


2. 카카오 Developers 에서 애플리케이션에서 추가

2-1. 내 어플리케이션


2-2. 애플리케이션 추가하기


2-3.애플리케이션 설정


2-3. Redirect URI 설정( 프론트 서버포트로 설정함 ) 

ex) localhost:3000


2-4. REST API키 확인 ( 뒤에서 쓸 ClientId )


3. Spring project yml 설정

security:
    oauth2:
      client:
        registration:
          kakao:
            client-id: {client-id} # 2-4의 REST API 키
            redirect-uri: {redirect-uri} # 2-3의 Redirect URI와 동일하게 작성
            authorization-grant-type: authorization_code
            client-authentication-method: POST
            client-name: Kakao
            scope:
              - profile_nickname
              - account_email
        provider:
          kakao:
            authorization-uri: https://kauth.kakao.com/oauth/authorize
            token-uri: https://kauth.kakao.com/oauth/token
            user-info-uri: https://kapi.kakao.com/v2/user/me
            user-name-attribute: id

프론트엔드 [Front-end] ( Next.js )

4. Front-end (Next.js/typescipt)

1. _document.tsx에 SDK추가

<script src="https://t1.kakaocdn.net/kakao_js_sdk/2.1.0/kakao.min.js" integrity="sha384-dpu02ieKC6NUeKFoGMOKz6102CLEWi9+5RQjWSV0ikYSFFd8M3Wp2reIcquJOemx" crossOrigin="anonymous"></script>
  1. 카카오 API 사용을 위해 카카오에서 제공하는 SDK 추가

2. _app.tsx에 Kakao init

_app.tsx

export default function App({ Component, pageProps }: AppProps) {
  function kakaoInit() { // 페이지가 로드되면 실행
    window.Kakao.init({kakao javascript 키});
    console.log(window.Kakao.isInitialized());
  }

  return (
  );
}
  1. _app.sx에 Kakao API 사용을 위해 window.Kakao.init 추가
  2. javascript키에 카카오개발자 에서 가져온 javascript키 입력

3. login.tsx(로그인 버튼을 넣을 페이지)

login.tsx

function kakaoLogin() {
    console.log(window.Kakao.Auth);
    window.Kakao.Auth.authorize({
      redirectUri: `{redirectUri}`, 
    });
  }
  1. Spring yml파일에 설정한 redirectUri와 동일하게 설정 ex) localhost:3000/kakao

4.kakao.tsx(redirectUri에 입력한 주소)

kakao.tsx

export default function Kakao() {
  const router = useRouter();
  const code = router.query.code;

useEffect(()=>{
  if(code !== undefined){
    axios.get(`${baseUrl}/login/kakao?code=${code}`).then((res)=>{
// backend에서 return한 값들을 처리
    })
  }
}, [code]);

  return (
          <h2>로그인 중입니다..</h2>
  );
};
  1. redirectUri를 호출해서 kakao.tsx로 이동
  2. Login에 성공하면 카카오에서 해당 url뒤에 code를 담아 반환해준다. (포트번호는 무시해도 된다.)

  1. url뒤에 code를 router.query.code 를 이용해서 받아올 수있다.
  2. 받아온 code를 파라미터로 넣어 Back-end에 api 요청한다.

이후에는 백엔드에서 처리


Back-end (Spring)

OauthController.java

@Controller
@RequiredArgsConstructor
@RequestMapping("/login")
@Slf4j
public class OauthController {
    private final KakaoAPI kakaoAPI;
    private final UserService userService;

    @ResponseBody
    @GetMapping("/kakao")
    public ResponseEntity<?> login(@RequestParam("code") String code, HttpServletResponse response) throws URISyntaxException {
        String res = "accesstoken 생성 완료";
        System.out.println("code :" + code); //파라미터로 받아온 code 확인
        String access_Token = kakaoAPI.getAccessToken(code); // code를 이용해 카카오 엑세스 토큰을 발급받음
        HashMap<String,Object> userInfo = kakaoAPI.getUserInfo(access_Token); //발급받은 엑세스 토큰으로 유저정보 가져옴
        System.out.println("userInfo = " + userInfo);

        // 회원 인지확인 (개인상황에 맞게 구현)
        userService.check(userInfo.get("email").toString(),userInfo.get("nickname").toString());
        return userService.kakaoLogin(userInfo.get("email").toString(),response);
    }

}
  1. 프론트에서 요청한 api를 수행

→ code로 Access토큰 발급 → 토큰을 통해 유저정보 가져옴 → 이후에는 개인 마다 구현

필자는 유저정보가 저장되어있는지 확인하기 위해 check 메서드를 통해 email, nickname을 DB와 비교해서 없으면 저장, 있다면 진행 → kakaoLogin을 통해 jwt 새로 발급후 redis에 저장 해서 진행하였음.


이슈

  1. RedirectUri설정을 하며 삽질을 너무 많이했다.
  2. 프론트와 백을 연결하려면 프론트에서 요청을 시작하는건 불가피 한 것 같다.
  3. 대부분의 블로그들이 백에서 Rest API로 통신해서 결과값만 확인하거나 프론트에서 전부 처리하는 예제가 대부분이어서 헷갈렸다.
  4. 구현을 하며 다양한 오류가 있었는데, 하고나니 별거 없음.

'개발 지식 > 정리' 카테고리의 다른 글

Spring 회원가입 email 인증  (0) 2023.04.01
AWS EC2 배포 이슈사항(mysql, jar파일 빌드)  (0) 2023.04.01
Swagger 기본 사용법  (0) 2023.03.20
Redis (레디스)  (0) 2023.03.18
REST API란? (REST, RESTFUL)  (0) 2023.03.12