사전 작업
- 애플리케이션 등록
주소 : https://developers.kakao.com/console/app
에서 카카오 애플리케이션 등록을 한다
1-1) 카카오 로그인 활성화 (필수❗) → off 상태면 시작도 안됌..
1-2) Redirect URI 설정
이 주소는 컨트롤러에서 맵핑하는 주소를 꼭 써야한다. ( 무조건‼‼)
1-3) 동의항목 설정
본인이 카카오 로그인시 가져올 정보를 선택하는 곳이다. 저는 테스트 용으로 한거라
아주 간단한 정보만 가져올수있고, 심사를 통해서 통과해야지 카카오에 등록된, 여러정보를 가져 올 수 있습니다…
1-4) 플랫폼 등록
플랫폼 등록을 해줍니다. 웹 도메인은 기본 로컬 주소를 등록 해줍니다.
이제 진짜 코드로 넘어가 보겠습니다.
#2 TEST
💡 스프링부트 카카오톡 로그인 기본적인 동작 구조
폼 요청 → 컨트롤러 응답→ 서비스 확인
서비스 확인후 return → 컨트롤러 다시 응답 → 폼 확인
카카오톡을 빗대어 설명하면 폼에 등록한 주소에서 카카오톡 code 및 token을 요청하고
컨트롤러에서 응답을 받고, 서비스에서 응답을 하기위한 코드를 작성하고 코드에 부합하면
code 및 token을 부여하여, 사이트에 로그인을 시키는 구조 이다.
(틀린게 있으면 지적 부탁 드립니다..!)
2-1) 폼
카카오톡 로고 이미지는 카카오 디벨로퍼에서 무료로 가져올 수 있습니다.
카카오 Developer : Kakao Developers
이 홈페이지에 들어가면 현 카카오 개발자 님들이 댓글 달시 답변도 해주고 정말 좋습니다
에러 관련 내용도 많기 때문에 찾아보면서 하면 좋습니다.
2-2) 컨트롤러
@Controller
@RequestMapping("/login")
public class LoginController {
@Autowired
UserGaipService uservice;
@Autowired
CompanyGaipService cservice;
@Autowired
SocialService socialService;
@GetMapping("/kakao")
public String kakaoLogin(@RequestParam(value = "code", required = false) String code,HttpSession httpSession, UserGaipDto userGaipDto) {
String access_Token = socialService.getAccessToekn(code);
HashMap<String, Object> userInfo = socialService.getUserInfo(access_Token);
System.out.println("userInfo==== "+userInfo); //userInfo==== {kakao_id=121201221, kakao_nickname="진현규" 떠야함}
String nickname = (String)userInfo.get("kakao_nickname");
String id = (String) userInfo.get("kakao_id");
Map<String, Integer> map = new HashMap<>();
int k = socialService.getSearchKakaoId(id);
map.put("count", k);
System.out.println(k);
if(k==1) {
httpSession.setAttribute("user_name",nickname);
httpSession.setAttribute("myid",id);
httpSession.setAttribute("access_Token", access_Token);
//DB에 아이디가 존재하면 바로 로그인
//추가 로직을 짜야함.
}
if(k==0) {
//DB에 아이다가 존재하지 않으면 회원가입 시킴.
//회원가입 축하 폼으로 넘겨야함 원래는
httpSession.setAttribute("user_name",nickname);
httpSession.setAttribute("myid",id);
httpSession.setAttribute("access_Token", access_Token);
userGaipDto.setUser_name(nickname);
userGaipDto.setUser_email(id);
socialService.kakaoInsert(userGaipDto);
System.out.println("이름 : " + nickname + " __ 이메일 : " + id);
}
return "redirect:/";
}
따로 설명은 나중에 추가하겠습니다!
일단 이 코드를 실행하면 DB에 카카오톡 id, 이름이 insert가 됩니다!
2-3) 서비스 (여기 코드가 좀 어지럽 습니다‼)
- 카카오톡 토큰 받아오는 코드
@Service
public class SocialService implements SocialInter {
@Autowired
SocialMapperInter socialMapperInter;
@Override
public String getAccessToekn(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"); //POST요청 필수입니다. GET시 오류남
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=본인RESTAPI코드");
sb.append("&redirect_uri=http://localhost:9000/login/kakao"); //본인 Redirect주소
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);
ObjectMapper objectMapper = new ObjectMapper();
Map<string, object=""> jsonMap = objectMapper.readValue(result, new TypeReference<map<string, object="">>(){
});
access_token = jsonMap.get("access_token").toString();
refresh_token = jsonMap.get("refresh_token").toString();
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;
}
</map<string,></string,>
- 카카오톡 정보 받아오는 코드.
@Override
public HashMap<string,object> getUserInfo(String access_Token) {
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("POST");
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);
String kakao_id = element.getAsJsonObject().get("id").getAsString();
System.out.println("카카오아이디 "+kakao_id);
System.out.println("result type: "+result.getClass().getName());
try {
UserGaipDto UserGaipDto = new UserGaipDto();
ObjectMapper objectMapper = new ObjectMapper();
Map<string, object=""> jsonMap = objectMapper.readValue(result, new TypeReference<map<string, object="">>() {
});
System.out.println(jsonMap.get("properties"));
Map<string, object=""> properties = (Map<string, object="">)
jsonMap.get("properties");
Map<string, object=""> kakao_account = (Map<string, object="">)
jsonMap.get("kakao_account");
String kakao_nickname = properties.get("nickname").toString();
userInfo.put("kakao_nickname", kakao_nickname);
userInfo.put("kakao_id", kakao_id);
}catch(Exception e) {
e.printStackTrace();
}
}catch(IOException e) {
e.printStackTrace();
}
return userInfo;
}
</string,></string,></string,></string,></map<string,></string,></string,></string,></string,object>
3) 카카오톡 로그인(회원가입) 시 insert 및 카카오톡 아이디 존재 유무 체크
@Override
public void kakaoInsert(UserGaipDto userGaipDto) {
socialMapperInter.kakaoInsert(userGaipDto);
}
@Override
public int getSearchKakaoId(String kakao_id) {
return socialMapperInter.getSearchKakaoId(kakao_id);
}
interface
@Mapper
@Repository
public interface SocialMapperInter {
//KAKAO
public String getAccessToekn(String authorize_code);
public HashMap<String,Object> getUserInfo(String access_Token);
public void kakaoInsert(UserGaipDto userGaipDto);
public void kakaoLogout(String access_Token); //로그아웃
public UserGaipDto findKakao(Map<String,Object> userinfo);
public int getSearchKakaoId(String kakao_id);
}
mapper
<mapper namespace="boot.data.mapper.SocialMapperInter">
<select id="findKaKao" parameterType="Map" resultType="ugaipdto">
select * from usergaip where user_email=#{user_email} and user_name = #{user_name}
</select>
<insert id="kakaoInsert" parameterType="ugaipdto">
insert into usergaip(user_email,user_gaipday,user_name) values (#{user_email},now(),#{user_name})
</insert>
<select id="getSearchKakaoId" parameterType="String" resultType="int">
select count(*) from usergaip where user_email = #{user_email}
</select>
</mapper>
DTO
@Data
@Alias("ugaipdto")
public class UserGaipDto {
private String user_name;
private String user_num;
private String user_email;
private String user_pass;
private Timestamp user_gaipday;
}
원래 회원가입 테이블에 insert하는 종류는 4개지만,
kakao 로그인을 통한 회원가입에서는 name이랑 id(=email)만 가져오기 때문에 sql문을 구성할 때 insert할 column을 지정해서 insert하였습니다.
위 방법을 따라하시면 간단한 카카오톡 로그인 + 회원가입을 진행할 수 있습니다
틀린 부분이 있다면 지적 해주세요 감사합니다.