[React+Django]Kakao Social Login

정선웅·2021년 4월 27일
2
post-thumbnail

개발순서

  1. Frontend에서 Kakao Login 버튼 구현
  2. Frontend에서 앱키를 사용해 카카오 서버와 통신, access token받기
  3. access token을 Backend(Django)로 보냄
  4. Backend에서 access token를 통해 사용자 정보를 받음
  5. 사용자 정보를 통해 JWT(Json Web Token)을 받고 회원가입 유무를 체크해 신규 가입 혹은 로그인

참고

  1. react-kakao-login
  2. all auth, rest-auth 등 Django의 다른 모듈은 사용하지 않았습니다. 오히려 더 복잡해지는거같아서ㅠ

1.Frontend Kakao login

https://www.npmjs.com/package/react-kakao-login

npm i react-kakao-login

카카오 로그인을 위해서 첫번째로 리액트 카카오 로그인을 받아준다

 <KakaoLogin
    token={token}
    onSuccess={console.log}
    onFail={console.error}
    onLogout={console.info}
  />

위와같은 구조로 되어있다

Token같은 경우는 Kakao Developers에서 앱키->Javascript키를 복사해서 붙여넣어주면된다.

이런걸 할 때 그냥 올려버리면 정보가 유출될 수 있으니 dotenv와 같은 모듈을 사용해주자

2.서버와 통신

https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#request-code

기본적으로 위 Docs를 많이 참조했다.

구현된 버튼을 클릭하면 성공시에 access token을 받을 수 있다. 여기서 주의할 점은 여기서 나온 토큰이 인가코드(access code)가 아니라 access token이라는 점이다. 잘은 모르겠는데 react-kakao-login을 사용하면 한단계를 건너뛰는 것 같다.

3.Backend로 토큰 보내기

  const kakaoResponse = async(response)=>{
        console.log(response.response.access_token)
        let res = await axios.get(
            "http://localhost:8000/rest-auth/kakao/",
            {
              params: 
              {
                  code:response.response.access_token
                },
            }
          );
          console.log(res)
    }

Django에서 미리 rest-auth/kakao/라는 서버를 켜놔야한다.

path('rest-auth/kakao/', KakaoLogin.as_view(), name='kakao_login'),

이런식으로 ㅎㅎ

그러면 views.py에서 구현해 놓은 KakaoLogin(View) class로 아까 받은 토큰이 이동된다.

4.사용자 정보받기

kakao_access_code=request.GET.get('code',None)
url="https://kapi.kakao.com/v2/user/me"
headers={
            "Authorization":f"Bearer {kakao_access_code}",
            "Content-type":"application/x-www-form-urlencoded; charset=utf-8"
        }
kakao_response=requests.post(url,headers=headers)
kakao_response=json.loads(kakao_response.text)

Class내에서 다음과 같이 구현해놓았다.

먼저 request.GET.get을 통해 code를 받아오고 이를 requests.post를 사용해 카카오로 보낸다(pip install requests해야함)

그러면 kakao_response로 원하는 사용자 정보를 받을 수 있다. 이 미리 설정한 사용자 정보 동의 항목을 바탕으로 가져와진다.

HTTP/1.1 200 OK
{
  "id":123456789,
  "kakao_account": { 
    "profile_needs_agreement": false,
    "profile": {
      "nickname": "홍길동",
      "thumbnail_image_url": "http://yyy.kakao.com/.../img_110x110.jpg",
      "profile_image_url": "http://yyy.kakao.com/dn/.../img_640x640.jpg"
    },
    "email_needs_agreement":false, 
    "is_email_valid": true,   
    "is_email_verified": true,   
    "email": "sample@sample.com"
    "age_range_needs_agreement":false,
    "age_range":"20~29",
    "birthday_needs_agreement":false,
    "birthday":"1130",
    "gender_needs_agreement":false,
    "gender":"female"
  },  
  "properties":{
     "nickname":"홍길동카톡",
     "thumbnail_image":"http://xxx.kakao.co.kr/.../aaa.jpg",
     "profile_image":"http://xxx.kakao.co.kr/.../bbb.jpg",
     "custom_field1":"23",
     "custom_field2":"여"
     ...
  },
}

위와같은 형태로 정보를 받을 수 있다.

5.회원 유무 판단, 로그인 or 회원가입

Django에 model에 미리 User Class를 구현해 놓는다.

위에서 받은 사용자 정보 중에 id항목은 사용자 고유 항목이기 때문에 중복이 발생하지 않는다. 이를 바탕으로 User 모델을 검색해보고 신규회원 유무를 확인한다.

if User.objects.filter(uid=kakao_response['id']).exists():
            user    = User.objects.get(uid=kakao_response['id'])
            jwt_token = jwt.encode({'id':user.id}, SECRET_KEY,ALGORITHM)

            return HttpResponse(f'id:{user.id}, name:{user.name}, token:{jwt_token}, exist:true')
else: 
            
            if kakao_response['kakao_account']['gender']=="male":
                gender=0
            else:
                gender=1            
            User(
                uid=kakao_response['id'],
                platform="1",
                user_email=kakao_response['kakao_account'].get('email',None),
                name=kakao_response['properties']['nickname'],
                gender=gender,
                
            ).save()
            user    = User.objects.get(uid=kakao_response['id'])
            jwt_token = jwt.encode({'id':user.id}, SECRET_KEY, ALGORITHM)
            return HttpResponse(f'id:{user.id}, name:{user.name}, token:{jwt_token}, exist:false')

회원일경우 id값을 바탕으로 JWT로 만들어준다. (secret_key 와 algorithm은 dotenv로 숨겨둔 값이다.) jwt사용법은 pip install jwt를 하고 찾아보면된다.

신규가입자일 경우 user모델에 사용자 정보를 저장해주고 위와 동일하게 react로 정보를 보내주면 된다.

profile
코린이 개발일지

1개의 댓글

comment-user-thumbnail
2021년 8월 13일

혹시 코드를 조금 더 자세히 볼 수 있을까요? 너무 도움되는 자료인거 같아서요 ㅠㅠ

답글 달기