본문 바로가기

카테고리 없음

[Spring/maven] 프로젝트 회고4. 카카오 로그인 API

매번 복잡하고 까다로운 회원가입 절차는 아무리 우리의 개인정보를

보호해준다고 해도 귀찮다.

이미 가입한 나의 정보를 가지고 다른 사이트에서 이용할 수 없을까? 

이러한 이유 때문에 거의 모든 웹사이트들은 소셜로그인(구글,카카오,네이버등) 을 사용한다.

나는 프로젝트 때 카카오로그인API를 이용하였고

로그인 정보를 DB에 저장하여 프로젝트 서비스를 이용하도록 구현하였다.

 

카카오로그인을 구현하기 위해서는 단순히 내 프로젝트의 코드 작성 뿐만 아니라

'카카오에 API를 쓰겠다' 라고 등록을 먼저 해야 한다.

 

등록 절차

구글에 카카오 developers를 검색 한 후 -> 로그인 -> 내어플리케이션 순으로 들어간다.

 

 

자신의 어플리케이션을 등록한다.

 

[플랫폼]에 들어가서 자신이 이용할 도메인 주소를 등록한다.

하단에 있는 redirect URI도 등록해주어야 한다. (자신이 사용할 컨트롤러 mapping 주소를 입력하면 됨) 

이렇게 설정을 마치면 [앱 키]에서 자신의 고유한 앱키를 볼 수 있는데 이를 이용해 코드를 작성하면 된다.

나같은 경우에는 REST API키 를 썼다.

 

동의 항목에서는 필수 값으로 닉네임을, 이메일과 프로필사진을 선택 값으로 넣었는데

이메일정보를 필수정보로 가져오려면 비즈니스 앱(유료)등록을 해야 한다.

(나의 경우에는 팀프로젝트이기 때문에 선택값으로만 주었다.)

 

users.xml

<!-- 카카오 정보 찾기 -->
	<select id="findKakao" parameterType="java.util.HashMap"
		resultType="com.kosta.petner.bean.Users">
		<![CDATA[
		select *
		from users 
		where nickname=#{nickname} and email=#{email}
		]]>
	</select>

	<!-- 카카오 정보 저장 (일반회원에 비해 저장되는 값이 적음) -->
	<insert id="kakaoInsert" parameterType="java.util.HashMap">
		<![CDATA[
		insert into 
			users(user_no,
					id,
					nickname, 
					email,
					user_level,
					user_auth, 
					joindate,
					file_no)
			values(seq_user_no.nextval,
					#{email},
					#{nickname},
					#{email},	
					'BRONZE',
					2,
					sysdate,
					0)
			]]>
	</insert>

카카오 정보를 불러오는 select문과 나의 DB에 저장할 insert문 두개의 쿼리문을 각각 작성한다.

 

usersDAO

	// 카카오유저 정보 저장
	void kakaoinsert(HashMap<String, Object> userInfo);

	// 카카오유저 정보확인
	Users findkakao(HashMap<String, Object> userInfo);

usersDAOImpl

// 카카오 정보 저장
	public void kakaoinsert(HashMap<String, Object> userInfo) {
		sqlSession.insert("mapper.users.kakaoInsert",userInfo);
	}

	// 카카오 정보 확인
	public Users findkakao(HashMap<String, Object> userInfo) {
		System.out.println("RN:"+userInfo.get("nickname"));
		System.out.println("RE:"+userInfo.get("email"));
		return sqlSession.selectOne("mapper.users.findKakao", userInfo);
	}

 

usersService

	// 카카오토큰받기
	public String getAccessToken(String authorize_code);

	// 카카오회원정보조회
	public Users getUserInfo(String access_Token);

usersServiceImpl

 

//카카오 로그인
	@Override
	public String getAccessToken (String authorize_code) {
		String access_Token = "";
		String refresh_Token = "";
		String reqURL = "https://kauth.kakao.com/oauth/token";
		try {
			URL url = new URL(reqURL);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");
			conn.setDoOutput(true);
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
			StringBuilder sb = new StringBuilder();
			sb.append("grant_type=authorization_code");
			sb.append("&client_id=본인의Rest API키"); //본인이 발급받은 key
			sb.append("&redirect_uri=본인의 mapping uri"); // 본인이 설정한 주소
			sb.append("&code=" + authorize_code);
			bw.write(sb.toString());
			bw.flush();
			int responseCode = conn.getResponseCode();
			System.out.println("responseCode : " + responseCode);
			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line = "";
			String result = "";
			while ((line = br.readLine()) != null) {
				result += line;
			}
			System.out.println("response body : " + result);
			JsonParser parser = new JsonParser();
			JsonElement element = parser.parse(result);
			access_Token = element.getAsJsonObject().get("access_token").getAsString();
			refresh_Token = element.getAsJsonObject().get("refresh_token").getAsString();
			System.out.println("access_token : " + access_Token);
			System.out.println("refresh_token : " + refresh_Token);
			br.close();
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return access_Token;
	}
	// 카카오 로그인 정보 저장
	@Override
	public Users getUserInfo(String access_Token) {
		
		 //    요청하는 클라이언트마다 가진 정보가 다를 수 있기에 HashMap타입으로 선언
		HashMap<String, Object> userInfo = new HashMap<String, Object>();
		String reqURL = "https://kapi.kakao.com/v2/user/me";
		try {
			URL url = new URL(reqURL);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setRequestProperty("Authorization", "Bearer " + access_Token);
			int responseCode = conn.getResponseCode();
			System.out.println("responseCode : " + responseCode);
			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line = "";
			String result = "";
			while ((line = br.readLine()) != null) {
				result += line;
			}
			System.out.println("response body : " + result);
			JsonParser parser = new JsonParser();
			JsonElement element = parser.parse(result);
			JsonObject properties = element.getAsJsonObject().get("properties").getAsJsonObject();
			JsonObject kakao_account = element.getAsJsonObject().get("kakao_account").getAsJsonObject();
			String nickname = properties.getAsJsonObject().get("nickname").getAsString();
			String email = kakao_account.getAsJsonObject().get("email").getAsString();
			userInfo.put("nickname", nickname);
			userInfo.put("email", email);
		} catch (IOException e) {
			e.printStackTrace();
		}
			// catch 아래 코드 추가.
			Users result = usersDAO.findkakao(userInfo);
			// 위 코드는 먼저 정보가 저장되있는지 확인하는 코드.
			System.out.println("S:" + result);
			if(result==null) {
			// result가 null이면 정보가 저장이 안되있는거므로 정보를 저장.
				usersDAO.kakaoinsert(userInfo);
				// 위 코드가 정보를 저장하기 위해 Repository로 보내는 코드임.
				return usersDAO.findkakao(userInfo);
				// 위 코드는 정보 저장 후 컨트롤러에 정보를 보내는 코드임.
				//  result를 리턴으로 보내면 null이 리턴되므로 위 코드를 사용.
			} else {
				return result;
				// 정보가 이미 있기 때문에 result를 리턴함.
			}
	        
		}

ServiceImpl에 주요 코드가 다 입력되어 있다. 여기서  자신의 rest API 키 값과 uri값을 설정해주어야 한다.

 

 

UsersController

	//카카오 로그인 토큰받기
		@RequestMapping(value="/kakaoLogin", method=RequestMethod.GET)
		public String kakaoLogin(@RequestParam(value = "code", required = false) String code) throws Exception {
			System.out.println("#########" + code);
			String access_Token = usersService.getAccessToken(code);
			Users authUser = usersService.getUserInfo(access_Token);
			
			System.out.println("###access_Token#### : " + access_Token);
			
			// 아래 코드가 추가되는 내용
			session.invalidate();
			// 위 코드는 session객체에 담긴 정보를 초기화 하는 코드.
			session.setAttribute("authUser", authUser);
			//session.setAttribute("kakaoN", userInfo);
			//session.setAttribute("kakaoE", userInfo.getK_email());
			// 위 2개의 코드는 닉네임과 이메일을 session객체에 담는 코드
			// jsp에서 ${sessionScope.kakaoN} 이런 형식으로 사용할 수 있다.
 
			return "redirect:/";
		}

카카오로그인 또한 일반로그인과 마찬가지로 통일시키기 위해 authUser라는 변수에 세션을 설정해 주었다.

 

loginForm.jsp

   <a class="p-2" href="https://kauth.kakao.com/oauth/authorize?client_id=REST API키주소&redirect_uri=uri주소 &response_type=code">
			<p class="login_option"><span class="pet_btn login_btn kakao_btn">카카오톡계정으로 로그인하기</span></p></a>

마지막으로 jsp파일에 카카오톡 버튼을 만들어주면 되는데  

 

client_id 에 자신의restAPI키주소

redirct_uri=자신의 uri(컨트롤러에 설정한) 주소를 입력하면 된다.