Spring / Gradle / Javascript 이용한 카카오 API 회원가입 로그인 구현
카카오 DB와 연동되는 회원가입 SQL문은 아래와 같습니다. (카카오로 회원가입을 하면 회원DB ;member 테이블 ; 에 기본값으로 지정한 회원정보가 입력이 됩니다.)
Sql
CREATE TABLE kakao(
name nvarchar2(30) not null,
email varchar2(200) primary key,
picture nvarchar2(300),
CONSTRAINT kakao_pk FOREIGN KEY(email)
REFERENCES member(memberEmail)
on delete cascade
);
CREATE TABLE member_email(
memberEmail VARCHAR2(200),
memberEmailYn NUMBER(1),
CONSTRAINT member_email FOREIGN KEY(memberEmail)
REFERENCES member(memberEmail)
on delete cascade
);
CREATE TABLE member_info(
memberNum NUMBER(6),
memberType NUMBER(5) not null,
CONSTRAINT memberInfo_pk FOREIGN KEY(memberNum)
REFERENCES member(memberNum)
on delete cascade
);
CREATE TABLE member(
memberNum NUMBER(6),
memberId VARCHAR2(50),
memberPw VARCHAR2(1000) NOT NULL,
memberName VARCHAR2(20),
memberBday DATE not null,
memberAddress VARCHAR2(300),
memberTel VARCHAR2(20),
memberPhone VARCHAR2(20) NOT NULL,
memberEmail VARCHAR2(200),
memberEmailYn NUMBER(1),
memberMileage NUMBER(6) DEFAULT 0,
CONSTRAINT memberNum_pk primary key (memberNum),
CONSTRAINT memberId_uq UNIQUE(memberId),
CONSTRAINT memberEmail_uq UNIQUE(memberEmail)
);
Domain - Kakao
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Kakao {
private String name;
private String email;
private String picture;
public Kakao() {}
public Kakao(Kakao kakao) {
this.name = kakao.getName();
this.email = kakao.getEmail();
this.picture = kakao.getPicture();
}
}
Service - KakaoService (컨트롤러에서 정보받아서 DB에 저장)
@Service
@RequiredArgsConstructor
public class KakaoService {
@Autowired
MemberMapper mapper;
private final GeneratePw generatePw;
private final HttpSession httpSession;
private final MemberRegisterService memberRegisterService;
private final AuthService authService;
public HashMap<String, Object> getUserInfo(String access_Token) {
HashMap<String, Object> userInfo = new HashMap<>();
String reqURL = "https://kapi.kakao.com/v2/user/me";
try {
URL url = new URL(reqURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
// 요청에 필요한 Header에 포함될 내용
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 profile_image = properties.getAsJsonObject().get("profile_image").getAsString();
String email = kakao_account.getAsJsonObject().get("email").getAsString();
// userInfo.put("nickname", nickname); //HashMap에 정보 담기
// userInfo.put("email", email);
// userInfo.put("profile_image", profile_image);
//세션 저장히기
Kakao kakao = new Kakao();
kakao.setName(nickname);
kakao.setEmail(email);
kakao.setPicture(profile_image);
String pw = generatePw.excuteGenerate();
String ph = new String("010-0000-0000");
Date bday = new Date("January 1,2022");
String id = new String("kakao");
String address = new String("기본 주소를 설정해 주세요");
String tel = new String("02-0000-0000");
if (mapper.findByEmailKakao(email) != null) { //이메일이 존재하면 그냥 이메일로 찾은 사용자정보 돌려준다
System.out.println("사용자 정보 있음 :"+email);
//httpSession.setAttribute("kakao", new Kakao(kakao));
//AuthInfo 세션에 저장하기
Member member = memberRegisterService.selectByEmailOnly(kakao.getEmail());
AuthInfo authInfo = new AuthInfo(member.getMemberId(), member.getMemberName(), member.getMemberNum(),member.getMemberPw(), kakao.getEmail(), kakao.getPicture(),member.getMemberType());
httpSession.setAttribute("authInfo", authInfo);
return userInfo;
} else {
Member newMember = new Member(0, id, pw, nickname, bday, address,
tel, ph, email, 0, 0);
Member newMemberInfo = new Member(0, 1); //회원타입 일반회원:1
mapper.insertMember(newMember);
mapper.insertMemberInfo(newMemberInfo);
mapper.saveKakao(kakao);
//httpSession.setAttribute("kakao", new Kakao(kakao));
//AuthInfo 세션에 저장하기
Member member = memberRegisterService.selectByEmailOnly(kakao.getEmail());
AuthInfo authInfo = new AuthInfo(member.getMemberId(), member.getMemberName(), member.getMemberNum(),member.getMemberPw(), kakao.getEmail(), kakao.getPicture(),member.getMemberType());
httpSession.setAttribute("authInfo", authInfo);
System.out.println("카카오 가입완료/ 세션 저장 완료");
}
} catch (IOException e) {
e.printStackTrace();
}
return userInfo;
}
}
Controller - LoginController
@RequiredArgsConstructor
@Controller
public class LoginController {
private final AuthService authService;
private final KakaoService kakaoService;
private final MemberRegisterService memberRegisterService;
@RequestMapping("/signin/kakao")
@ResponseBody
public HashMap<String, Object> kakao(Model model, @RequestBody String accessToken) { //json으로 토큰 받아서 서버에 전송. 가입실행
HashMap<String, Object> userInfo = kakaoService.getUserInfo(accessToken);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("result",userInfo);
return map;
}
Templates - signin - loginForm.html
<head>
<script src="https://developers.kakao.com/sdk/js/kakao.js"></script>
</head>
<body>
.
.
.
<div class="d-grid">
<button class="btn btn-block btn-login" type="button" style="background-color: #e0C097; border: 0;"
onclick="javascript:kakaoLogin();">
<i class="fa fa-comment"></i> 카카오 계정으로 로그인
</button>
</div>
.
.
.
<script>
function onSignIn(){
var auth2 = gapi.auth2.getAuthInstance();
if(auth2.isSignedIn.get()){
var profile = auth2.currentUser.get().getBasicProfile();
googleLoginPro(profile)
console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present.
}
}
</script>
<script>
Kakao.init('카카오 JavaScript Key 입력');
function kakaoLogin() {
Kakao.Auth.login({
success: function(response) {
Kakao.API.request({ // 사용자 정보 가져오기
url: '/v2/user/me',
success: (response) => {
var accessToken = Kakao.Auth.getAccessToken();
Kakao.Auth.setAccessToken(accessToken);
$.ajax({
type : 'POST',
url : '/signin/kakao',
data : JSON.stringify(accessToken),
dataType :'json',
accept: 'application/json',
contentType : 'application/json; charset=UTF-8',
success : function(result) {
console.log("데이터 보내기 성공");
console.log(result);
window.location.href='/signin/loginSuccess' //리다이렉트 되는 코드
},
error: function(request, status, error){
alert("code: "+request.status+"\n"+"message: 선택사항의 이메일 주소를 체크해주세요."+"\n"+"error: "+error);
}
}); // ajax 끝
}
});
},
fail: function(error) {
alert(error);
}
});
}
</script>
.
.
</body>
흐름은 이렇습니다.
프론트부분에서 (html)에서 사용자가 정보제공동의 - 카카오에 로그인 - 사용자 정보를 Ajax 이용해 컨트롤러넘김 - 컨트롤러에서는 서비스를 호출해서 서비스부분에서 디비에 정보를 저장합니다.
로그인완료시 리다이렉트 되는 페이지를 잘 꾸며주면 아래처럼 로그인 / 회원가입 완료시 깔끔한 페이지가 나오는것을 볼수 있습니다!
그리고 이렇게 로그인후 들어간 회원정보 수정 페이지에서 서비스페이지에서 넣었던 기본 정보도 잘 들어가있음을 확인할 수 있습니다.
728x90
'Portfolio' 카테고리의 다른 글
Spring/Gradle/Mybatis/Thymeleaf 검색기능있는 기본게시판 구현 (0) | 2022.05.24 |
---|