카카오로그인 연동 방식 변경

-oauth 테이블 삭제
-비밀번호 변경 기능 추가(카카오톡 나에게 보내기)
This commit is contained in:
2018-03-18 05:44:20 +09:00
parent bd26ee858c
commit 6130bd22cb
8 changed files with 149 additions and 39 deletions
+23 -1
View File
@@ -203,4 +203,26 @@ function toInt($val, $force=false){
return intval($val);
}
throw new InvalidArgumentException('올바르지 않은 타입형 :'.$val);
}
}
/**
* Generate a random string, using a cryptographically secure
* pseudorandom number generator (random_int)
*
* For PHP 7, random_int is a PHP core function
* For PHP 5.x, depends on https://github.com/paragonie/random_compat
*
* @param int $length How many characters do we want?
* @param string $keyspace A string of all possible characters
* to select from
* @return string
*/
function random_str($length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
$str = '';
$max = mb_strlen($keyspace, '8bit') - 1;
for ($i = 0; $i < $length; ++$i) {
$str .= $keyspace[random_int(0, $max)];
}
return $str;
}
+1 -22
View File
@@ -43,33 +43,12 @@ CREATE TABLE `member` (
)
ENGINE=InnoDB DEFAULT CHARSET=UTF8;
-- 인증 테이블
CREATE TABLE `auth_kakao` (
`no` BIGINT(20) NOT NULL AUTO_INCREMENT,
`id` BIGINT(20) NOT NULL COMMENT 'after signup',
`access_token` CHAR(128) NOT NULL COMMENT 'after token',
`refresh_token` CHAR(128) NOT NULL,
`expires` DATETIME NOT NULL,
`refresh_token_expires` DATETIME NOT NULL,
`datetime` DATETIME NOT NULL,
`email` VARCHAR(128) NOT NULL,
PRIMARY KEY (`no`),
INDEX `access_token` (`access_token`),
INDEX `id` (`id`),
INDEX `expires` (`expires`),
INDEX `email` (`email`),
INDEX `refresh_expires` (`refresh_token_expires`),
INDEX `datetime` (`datetime`)
)
ENGINE=InnoDB DEFAULT CHARSET=UTF8;
-- 로그인 로그 테이블
CREATE TABLE `member_log` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`member_no` INT(11) NOT NULL,
`date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`action_type` ENUM('reg','try_login','login','logout','oauth','make_general','access_server') NOT NULL,
`action_type` ENUM('reg','try_login','login','logout','oauth','change_pw','make_general','access_server') NOT NULL,
`action` TEXT NULL DEFAULT NULL COMMENT 'JSON',
PRIMARY KEY (`id`),
INDEX `action` (`member_no`, `action_type`, `date`),
+4 -1
View File
@@ -53,7 +53,7 @@ function doLoginUsingOAuth(retry=false){
alert(obj.reason);
}
else{
getOAuthToken();
getOAuthToken('login');
}
}
else{
@@ -71,6 +71,9 @@ function postOAuthResult(result){
if(oauthMode=='change_pw'){
sendTempPasswordToKakaoTalk();
}
else{
doLoginUsingOAuth();
}
}
else{
alert('예외 발생!');
+113 -1
View File
@@ -1,6 +1,118 @@
<?php
require('_common.php');
require(ROOT.'/f_func/class._Session.php');
require(ROOT.'/f_config/DB.php');
require(ROOT.'/f_func/class._Time.php');
require('kakao.php');
require('kakao.php');
use utilphp\util as util;
$nowDate = _Time::DatetimeNow();
$SESSION = new _Session();
if(!$SESSION->isLoggedIn()){
returnJson([
'result'=>false,
'reason'=>'로그인이 되어있지 않습니다'
]);
}
$userID = $SESSION->NoMember();
$access_token = util::array_get($_SESSION['access_token']);
$expires = util::array_get($_SESSION['expires']);
$refresh_token = util::array_get($_SESSION['refresh_token']);
$refresh_token_expires = util::array_get($_SESSION['refresh_token_expires']);
if(!$access_token || !$expires){
returnJson([
'result'=>false,
'reason'=>'카카오로그인이 이루어지지 않았습니다.'
]);
}
//TODO: join과 login의 동작이 비슷하다. helper class로 묶자.
$restAPI = new Kakao_REST_API_Helper($access_token);
if($expires < $nowDate && (!$refresh_token || ($refresh_token_expires < $nowDate))){
returnJson([
'result'=>false,
'reason'=>'로그인 토큰 만료.'.$refresh_token_expires.' 다시 카카오로그인을 수행해주세요.'
]);
}
if($expires < $nowDate){
unset($_SESSION['kaccount_email']);
$email = null;
$result = $restAPI->refresh_access_token($refresh_token);
if(!isset($refresh_token)){
returnJson([
'result'=>false,
'reason'=>'카카오 로그인 과정 중 추가 갱신 절차를 실패했습니다'
]);
}
$access_token = $result['access_token'];
$expires = _Time::DatetimeFromNowSecond($nowDate, $result['expires_in']);
if(isset($result['refresh_token'])){
$refresh_token = util::array_get($result['refresh_token']);
$refresh_token_expires = _Time::DatetimeFromNowSecond($nowDate, $result['refresh_token_expires_in']);
}
}
getRootDB()->query("lock tables member write, member_log write");
$isUser = getRootDB()->queryFirstRow(
'SELECT count(`no`) from member where no=%i',$userID);
if(!$isUser){
returnJson([
'result'=>false,
'reason'=>'회원이 아닙니다. 관리자에게 문의해주세요.'
]);
}
$newPassword = random_str(6);
$tmpPassword = hashPassword(getGlobalSalt(), $newPassword);
$newSalt = bin2hex(random_bytes(8));
$newFinalPassword = hashPassword($newSalt, $tmpPassword);
$sendResult = $restAPI->talk_to_me_default([
"object_type"=> "text",
"text"=> "임시 비밀번호는 $newPassword 입니다. 로그인 후 바로 다른 비밀번호로 변경해주세요.",
"link"=> [
"web_url"=> getServerBasepath(),
"mobile_web_url" => getServerBasepath()
],
"button_title"=> "로그인 페이지 열기"
]);
$sendResult['code'] = util::array_get($sendResult['code'], 0);
if($sendResult['code'] < 0){
returnJson([
'result'=>false,
'reason'=>'카카오톡 메시지를 보내지 못했습니다.'
]);
}
getRootDB()->update('member', [
'pw'=>$newFinalPassword,
'salt'=>$newSalt
],'no=%i', $userID);
getRootDB()->insert('member_log', [
'member_no'=>$userID,
'date'=>$nowDate,
'action_type'=>'change_pw',
'action'=>json_encode([
'type'=>'kakao',
'no'=>$userID,
'token'=>$access_token
], JSON_UNESCAPED_UNICODE)
]);
getRootDB()->query("unlock tables");
returnJson([
'result'=>true,
'reason'=>'success'
]);
+1 -11
View File
@@ -1,7 +1,7 @@
<?php
require_once('_common.php');
require('lib.join.php');
require(ROOT.'/f_func/class._Time.php');
require_once(ROOT.'/f_func/class._Time.php');
require('kakao.php');
use utilphp\util as util;
@@ -142,16 +142,6 @@ if($emailChk !== true){
}
//모든 절차 종료. 등록.
getRootDB()->insert('auth_kakao',[
'id'=>$kakaoID,
'access_token'=>$access_token,
'refresh_token'=>$refresh_token,
'expires'=>$expires,
'refresh_token_expires'=>$refresh_token_expires,
'datetime'=>$nowDate,
'email'=>$email
]);
getRootDB()->insert('member',[
'oauth_id' => $kakaoID,
'oauth_type' => 'KAKAO',
+5 -1
View File
@@ -232,7 +232,11 @@ class Kakao_REST_API_Helper
}
public function talk_to_me_default($req){
return $this->request(TalkPath::$TALK_TO_ME_DEFAULT, json_encode($req), 'POST');
$params = [
'template_object' => json_encode($req)
];
return $this->request(Talk_Path::$TALK_TO_ME_DEFAULT, $params, 'POST');
}
+1 -1
View File
@@ -2,7 +2,7 @@
require_once('_common.php');
require_once(__dir__.'/../d_setting/conf.php');
require_once(__dir__.'/../f_func/func.php');
require(ROOT.'/f_func/class._Time.php');
require_once(ROOT.'/f_func/class._Time.php');
function checkUsernameDup($username){
if(!$username){
+1 -1
View File
@@ -41,7 +41,7 @@ function randBool($prob = 0.5){
}
/**
* 로그인한 유저의 전역 id를 받아옴
* 로그인한 유저의 전역 id(숫자)를 받아옴
*
* @return int|null
*/