관리 메뉴

웹개발자의 기지개

[PHP] 카카오 로그인 ( with 네이버 로그인 ) 본문

PHP

[PHP] 카카오 로그인 ( with 네이버 로그인 )

http://portfolio.wonpaper.net 2023. 8. 10. 10:18

카카오 개발자 센터에서 로그인이 필요하다.

 

https://developers.kakao.com/console/app

 

카카오계정

 

accounts.kakao.com

 

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

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

 

관련 키값들이 필요하다. 

Rest API 키값을 이용하면된다.

그리고, Client Secret 키도 추가하려면 설정해주면 되는데, 선택사항이다.

 

 

 

 

기기별로 추가 등록 관리할 수 있다.

 

 

필자는 아래와 회원테이블 이미지를 보는것처럼

userid PK 

naver_id , naver_email, kakao_id, kakao_img, kakao_email 등으로 추가 칼럼을 만들고 

네이버로그인이나 카카오로그인 최초 로그인시에 각각 해당 칼럼에 알맞게 넣을 수 있는 별도 공간을 추가로 마련하였다.

 

 

[login.php]

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<? 
include "../include/head.php";
 
define('NAVER_CLIENT_ID', 'aaaaaaa');
define('NAVER_CLIENT_SECRET', 'ccccccc');
define('NAVER_CALLBACK_URL', 'http://도메인/member/callback_member.php');
$naverUrl = "https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=".NAVER_CLIENT_ID."&redirect_uri=".urlencode(NAVER_CALLBACK_URL);
 
define('KAKAO_CLIENT_ID', 'aaaaaa'); 
define('KAKAO_CLIENT_SECRET', 'bbbbbbbb'); 
define('KAKAO_CALLBACK_URL','http://도메인/member/callback_kakao_member.php');
 
$kakao_state = md5(microtime() . mt_rand()); 
$_SESSION['kakao_state'] = $kakao_state;
$kakaoUrl = "https://kauth.kakao.com/oauth/authorize?client_id=".KAKAO_CLIENT_ID."&redirect_uri=".urlencode(KAKAO_CALLBACK_URL)."&response_type=code&state=".$kakao_state;
?>
 
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/xeicon@2.3.3/xeicon.min.css">
 
<form name='frm' method='post'>
    
    아이디 <input type="text" name="user_id"><br>
    비밀번호 <input type="password" name="passwd1"><br>
 
    <input type="button" value="로그인"><br>
    <div class="soc_login">
        <div class="login_btn02 h10"><a href="<?=$naverUrl?>"><i class="xi-naver xi-x"></i>네이버로 시작하기</a></div>
        <div class="login_btn01 h10"><a href="<?=$kakaoUrl?>"><i class="xi-kakaotalk xi-x"></i>카카오로 시작하기</a></div>
    </div>
</form>
cs

 

[ /member/callback_kakao_member.php ]

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?
session_start(); 
 
define('KAKAO_CLIENT_ID''aaaaaaaaa'); 
define('KAKAO_CLIENT_SECRET''cccccccc'); 
define('KAKAO_CALLBACK_URL','http://도메인/member/callback_kakao_member.php');
 
if ($_SESSION['kakao_state'!= $_GET['state']) { 
    echo "<script>location.href='/member/login.php';</script>";
    exit;
}
 
if ($_GET["code"]) {
    //사용자 토큰 받기
    $code   = $_GET["code"]; 
    $params = sprintf( 'grant_type=authorization_code&client_id=%s&redirect_uri=%s&code=%s', KAKAO_CLIENT_ID, KAKAO_CALLBACK_URL, $code);    
    $TOKEN_API_URL = "https://kauth.kakao.com/oauth/token"
    $opts = array(
        CURLOPT_URL => $TOKEN_API_URL
        CURLOPT_SSL_VERIFYPEER => false
        CURLOPT_SSLVERSION => 1// TLS
        CURLOPT_POST => true
        CURLOPT_POSTFIELDS => $params
        CURLOPT_RETURNTRANSFER => true
        CURLOPT_HEADER => false 
    );
 
    $curlSession = curl_init(); 
    curl_setopt_array($curlSession$opts); 
    $accessTokenJson = curl_exec($curlSession); 
    curl_close($curlSession); 
 
    $responseArr = json_decode($accessTokenJsontrue);
    $_SESSION['kakao_access_token'= $responseArr['access_token'];
    $_SESSION['kakao_refresh_token'= $responseArr['refresh_token'];
    $_SESSION['kakao_refresh_token_expires_in'= $responseArr['refresh_token_expires_in'];
 
    //사용자 정보 가저오기
    $USER_API_URL"https://kapi.kakao.com/v2/user/me"
    $opts = array(
        CURLOPT_URL => $USER_API_URL,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSLVERSION => 1,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => false,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => array(
            "Authorization: Bearer " . $responseArr['access_token']
        )
    );
 
    $curlSession = curl_init();
    curl_setopt_array($curlSession$opts);
    $accessUserJson = curl_exec($curlSession);
    curl_close($curlSession);
 
    $me_responseArr = json_decode($accessUserJsontrue);
 
 
 
//    print_r($me_responseArr);
//    Array ( [msg] => target ID is not supplied. [code] => -401 )
 
 
    if ($me_responseArr['id']) {
 
        include $_SERVER['DOCUMENT_ROOT'].  "/inc/config.php";
 
        $query = "select * from Site_Member where kakao_email='"$me_responseArr['kakao_account']['email'] ."'";
        $memRes = mysql_query($query);
        $memRow = mysql_fetch_array($memRes);
 
        // 회원아이디(kakao_ 접두사에 카카오 붙여줌)
        $mb_uid = 'kakao_'.$me_responseArr['id'];
 
        if ($memRow["kakao_email"]) {
            // 멤버 DB에 토큰값 업데이트 $responseArr['access_token']
            // 로그인
            
            $_SESSION[id]      = $memRow['userid'];
            $_SESSION[name]    = $memRow['name'];
 
            $list = mysql_fetch_array(mysql_query("select * from Site_Member_Info where userid='".$memRow['userid']."'"));
            $_SESSION[email] = $list[email];
            $cel_division = explode("-"$list[cel]);
            $_SESSION[cel1] = $cel_division[0];
            $_SESSION[cel2] = $cel_division[1];
            $_SESSION[cel3] = $cel_division[2];
 
            echo("<meta http-equiv='refresh' content='0;URL=/'>");
            exit;
 
        } else { // 없다면 회원가입한다.
 
            // 회원아이디 $mb_uid - kakao_id 칼럼에 삽입
            // properties 항목은 카카오 회원이 설정한 경우만 넘겨 받습니다.
            $mb_nickname = $me_responseArr['properties']['nickname']; // 닉네임
            $mb_profile_image = $me_responseArr['properties']['profile_image']; // 프로필 이미지
            $mb_thumbnail_image = $me_responseArr['properties']['thumbnail_image']; // 프로필 이미지
 
            $mb_email = $me_responseArr['kakao_account']['email']; // 이메일
            $mb_gender = $me_responseArr['kakao_account']['gender']; // 성별 female/male
            $mb_age = $me_responseArr['kakao_account']['age_range']; // 연령대
            $mb_birthday = $me_responseArr['kakao_account']['birthday']; // 생일
 
            // 멤버 DB에 토큰과 회원정보를 넣고 로그인
            $reg_date = time();
            //$query = "insert into member (email,name,naver_id,member_id,member_passwd,post1,address1,address2,hp,level,reg_date,profile_img,kakao_id) values ('".$mb_email."','".$mb_nickname."','','".$mb_email."','','','','','','1','$reg_date','".$mb_profile_image."','".$mb_uid."')";
 
            $query = "insert into Site_Member (userid,passwd,name,user_level,user_grade,wdate,login_date,naver_id,naver_email,kakao_id,kakao_img,kakao_email) values ('".$mb_uid."','','$mb_nickname','5','N','".$reg_date."','0','','','".$mb_uid."','".$mb_profile_image."','".$mb_email."')";            
            mysql_query($query) or die("Insert error! [1]");
 
            $_SESSION[id]      = $mb_uid;
            $_SESSION[name]    = $mb_nickname;
            $_SESSION[email]   = $mb_email;
 
            $query1 = "insert into Site_Member_Info (userid,nickname,homepage,jumin,email,email_chk,zip,addr1,addr2,tel,cel,job,birth,solar,sex,photo,etc) values ('".$mb_uid."','$mb_nickname','','','".$mb_email."','y','','','','','','','','','','','')";
            mysql_query($query1) or die("Insert error! [2]");
 
            echo("<meta http-equiv='refresh' content='0;URL=/'>");
 
            exit;
        }
 
    } else {
        echo "<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>";
        echo "<script>alert('회원정보를 가져오지 못했습니다.');location.href='/member/login.php';</script>";
        exit;
    }
 
 
}
 
?>
cs

 

 

[ /member/callback_member.php ] - 네이버 로그인

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?
session_start();
 
define('NAVER_CLIENT_ID''aaaaaaaa');
define('NAVER_CLIENT_SECRET''cccccc');
define('NAVER_CALLBACK_URL''http://도메인/member/callback_member.php');
 
 
$naver_curl = "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code&client_id=".NAVER_CLIENT_ID."&client_secret=".NAVER_CLIENT_SECRET."&redirect_uri=".urlencode(NAVER_CALLBACK_URL)."&code=".$_GET['code'];
 
// 토큰값 가져오기
$is_post = false;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $naver_curl);
curl_setopt($ch, CURLOPT_POST, $is_post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
$response = curl_exec ($ch);
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close ($ch);
 
if($status_code == 200){
    $responseArr = json_decode($responsetrue);
 
      // 토큰값으로 네이버 회원정보 가져오기
      $headers = array'Content-Type: application/json', sprintf('Authorization: Bearer %s'$responseArr['access_token']) );
      $is_post = false;
      $me_ch = curl_init();
      curl_setopt($me_ch, CURLOPT_URL, "https://openapi.naver.com/v1/nid/me");
      curl_setopt($me_ch, CURLOPT_POST, $is_post );
      curl_setopt($me_ch, CURLOPT_HTTPHEADER, $headers);
      curl_setopt($me_ch, CURLOPT_RETURNTRANSFER, true);
      $res = curl_exec ($me_ch);
      curl_close ($me_ch);
      $res_data = json_decode($res , true);
 
 
    /*
    {
      "resultcode": "00",
      "message": "success",
      "response": {
        "email": "openapi@naver.com",
        "nickname": "OpenAPI",
        "profile_image": "https://ssl.pstatic.net/static/pwe/address/nodata_33x33.gif",
        "age": "40-49",
        "gender": "F",
        "id": "32742776",
        "name": "오픈 API",
        "birthday": "10-01"
      }
    }
    */
 
//    print_r($res_data);
//    Array ( [resultcode] => 00 [message] => success [response] => Array ( [id] => sdP6So8v2EhWsgQKgDzrAdzpZwGdEw7Lb1U83OMFgc8 [email] => neomeskin@naver.com [name] => �댁��� ) )
 
 
      if ($res_data['response']['id']) {
      //해당 아이디값을 정상적으로 가져온다면 디비에 해당 아이디로 회원가입 여부 확인 하여 회원 가입을 하였으면 자동 로그인 구현.
 
        // 회원아이디(naver_ 접두사에 카카오 붙여줌)
        $mb_uid = 'naver_'.$res_data['response']['id'];
 
            include $_SERVER['DOCUMENT_ROOT'].  "/inc/config.php";
 
            $query = "select * from Site_Member where naver_email='"$res_data['response']['email'] ."'";
            $memRes = mysql_query($query);
            $memRow = mysql_fetch_array($memRes);
 
            if($memRow[naver_email]){ // 이미 가입된 회원이면 자동로그인한다.
 
                $_SESSION[id]      = $memRow['userid'];
                $_SESSION[name]    = $memRow['name'];
 
                $list = mysql_fetch_array(mysql_query("select * from Site_Member_Info where userid='".$memRow['userid']."'"));
                $_SESSION[email] = $list[email];
                $cel_division = explode("-"$list[cel]);
                $_SESSION[cel1] = $cel_division[0];
                $_SESSION[cel2] = $cel_division[1];
                $_SESSION[cel3] = $cel_division[2];                
 
 
                echo("<meta http-equiv='refresh' content='0;URL=/'>");
                exit;
            } else {          // 새로 회원가입을 하고 자동로그인추가한다.
 
                $reg_date = time();
                //$query = "insert into member (email,name,naver_id,member_id,member_passwd,post1,address1,address2,hp,level,reg_date,profile_img) values ('".$res_data['response']['email']."','".$res_data['response']['name']."','".$res_data['response']['id']."','".$res_data['response']['email']."','','','','','','1','$reg_date','".$res_data['response']['profile_image']."')";
                
                $query = "insert into Site_Member (userid,passwd,name,user_level,user_grade,wdate,login_date,naver_id,naver_email,kakao_id,kakao_img,kakao_email) values ('".$mb_uid."','','".$res_data['response']['name']."','5','N','".$reg_date."','0','".$res_data['response']['id']."','".$res_data['response']['email']."','','','')";
 
                echo $query;
                exit;
                mysql_query($query) or die("Insert error! [1]");
 
                $_SESSION[id]      = $mb_uid;
                $_SESSION[name]    = $res_data['response']['name'];
                $_SESSION[email]   = $res_data['response']['email'];
 
                $query1 = "insert into Site_Member_Info (userid,nickname,homepage,jumin,email,email_chk,zip,addr1,addr2,tel,cel,job,birth,solar,sex,photo,etc) values ('".$mb_uid."','".$res_data['response']['name']."','','','".$res_data['response']['email']."','y','','','','','','','','','','','')";
                mysql_query($query1) or die("Insert error! [2]");
 
                echo("<meta http-equiv='refresh' content='0;URL=/'>");
                exit;
            }
 
 
      } else {
                echo("<meta http-equiv='refresh' content='0;URL=/member/login.php'>");
      }
}
?>
 
cs

 

 

 

 

 

참고 : https://blog.yesyo.com/entry/%EC%B9%B4%EC%B9%B4%EC%98%A4-%EC%82%AC%EC%9A%A9%EC%9E%90-%EA%B4%80%EB%A6%AC-%EC%B9%B4%EC%B9%B4%EC%98%A4-%EC%95%84%EC%9D%B4%EB%94%94%EB%A1%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-PHP-%EC%97%B0%EB%8F%99

Comments