จากเนื้อหาตอนที่ 2 เราได้รู้จักวิธีการ Integrated Social Login
ของแต่ละ platform ซึ่งสามารถแยกนำไปประยุกต์ ใช้งาน
เฉพาะ platform ที่ต้องการ หรือจะใช้รวมกันทั้งหมดก็ได้
เราสามารถเรียกดูข้อมูลเบื้องต้นของผู้ใช้ที่ล็อกอินด้วยบัญชี social ต่างๆ
ทบทวนเนื้อหาได้ที่บทความ
การใช้งาน PHP Library ดึงข้อมูล Social API อัพเดทปี 2020 ตอนที่ 2 http://niik.in/987
https://www.ninenik.com/content.php?arti_id=987 via @ninenik
เนื้อหาตอนต่อไปนี้ เราจะมาประยุกต์เพิ่มเติม โดยนำมาใช้งานกับระบบสมาชิก ซึ่งจะขอแนะนำ
ในสองรูปแบบ คือ แบบแรก เป็นการสร้างระบบสมัครสมาชิก โดยที่เราไม่ต้องออกแบบหน้าตา
แบบฟอร์มการตรวจสอบการสมัครสมาชิกใหม่ หรือบัญชีผู้ใช้ใหม่ในระบบของเรา แต่ใช้วิธีสร้างโดย
ใช้ข้อมูลจากการล็อกอินผ่านระบบ social login เป็นข้อมูลเบื้องต้น
และแบบที่สอง การเชื่อมโยงบัญชีผู้ใช้ หรือระบบสมาชิกเดิมของเราที่มีอยู่แล้ว เพื่อกำหนดให้ผู้ใช้นั้น
เลือกที่จะล็อกอินด้วยบัญชี social อื่นๆ แทนได้
โดยในเนื้อหา จะพูดถึงเรื่องการจัดเก็บ และใช้งานร่วมกับฐานข้อมูล การออกแบบโครงสร้างฐานข้อมูลต่างๆ
จะเป็นแนวทางเท่านั้น สามารถปรับประยุกต์เพิ่มเติมตามรูปแบบของเราเองได้
สร้างระบบสมาชิกด้วยบัญชีผู้ใช้ Social
ก่อนอื่นให้เข้าใจก่อนว่า ระบบสมาชิกใดๆ จะมีข้อมูลหนึ่งๆ ที่ไม่ซ้ำกัน นั้นคือ ID ของบัญชีผู้ใช้นั้น โดยค่า ID
จะเป็นค่าใด ก็ได้ ไม่จำเป็นจะต้องลำดับเลข ID แต่อาจจะเป็นอีเมล เบอร์โทร หรือเลขบัตรประชาชน ซึ่งเป็นค่า
ที่เป็นเฉพาะหรือ unique ไม่ซ้ำกัน ก็สามารถอ้างอิงเป็น ID ระบุตัวตันของสมาชิกนั้นๆ ได้
ถ้าระบบของเรา เลือกใช้งานเพียง platform เดียว สมมติเช่น มีแค่ระบบล็อกอินผ่าน facebook นั่่นคือบัญชี
ผู้ใช้ facebook หนึ่งคน ก็สามารถสร้างเป็นบัญชีสมาชิกในระบบของเราได้ 1 บัญชี โดยใช้ค่าค่าหนึ่ง เช่น ID ของ
บัญชี facebook เป็นตัวเชื่อมความสัมพันธ์ของข้อมูล โดยหากเคยสมัครใช้งานด้วยบัญชี facebook นั้นๆ แล้วก็
ให้ทำการล็อกอินเข้าใช้งาน ได้ไม่ต้องสร้างบัญชีผู้ใช้ใหม่ เข้าใจอย่างง่ายก็คือ สร้างบัญชีผู้ใช้ใหม่ในระบบของเรา
แค่ครั้งแรกครั้งเดียว
อย่างไรก็ตาม เมื่อเรามีการใช้งานการล็อกอินด้วย social มากกว่า 1 platform ผู้ใช้คนเดิม อาจจะมีการสร้างบัญชี
ผู้ใช้ในระบบสมาชิกของเรา จากทั้ง 2 platfom ได้ เช่น เคยล็อกอินด้วย facebook ในครั้งแรก ครั้งต่อมาเปลี่ยนมา
ล็อกอินด้วย google ซึ่งแน่นอนว่า ทั้งสอง platform โดยส่วนใหญ่แล้ว จะไม่มีความเชื่อมโยงหรือสัมพันธ์ของข้อมูล
ID ของ google กับ facebook ก็เป็นคนละค่า ถึงแม้จะเป็นไปได้ว่า ที่ข้อมูลเชิงล็กอื่นๆ อาจจะมีการใช้งานร่วมกับ เช่น
อาจจะใช้อีเมล หรือใช้เบอร์โทรเดียวกัน ซึ่งแน่นอนว่าการเข้าถึงข้อมูลพิเศษนั้น ก็จำเป็นต้องการดำเนินการต่างๆ มากมาย
ดังนั้น ในที่นี้ เราจะพูดถึงหลักการใช้งานทั่วๆ ไป เมื่อข้อมูลยากที่จะเชื่อมโยงกัน การล็อกอินด้วยอีก platform ก็คือ
การสร้างบัญชีผู้ใช้ใหม่ในระบบของเรานั่นเอง
โครงสร้างตารางฐานข้อมูลระบบสมาชิก
-- -- Table structure for table `tbl_user` -- CREATE TABLE `tbl_user` ( `id` int(11) NOT NULL, `user_id` varchar(255) NOT NULL, `name` varchar(100) NOT NULL, `email` varchar(100) NOT NULL, `picture` varchar(100) NOT NULL, `social_token` varchar(255) NOT NULL, `create_date` timestamp NOT NULL DEFAULT current_timestamp(), `last_login` datetime NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Indexes for dumped tables -- -- -- Indexes for table `tbl_user` -- ALTER TABLE `tbl_user` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `user_id` (`user_id`); -- -- AUTO_INCREMENT for dumped tables -- -- -- AUTO_INCREMENT for table `tbl_user` -- ALTER TABLE `tbl_user` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; COMMIT;
ฟิลด์ id เราจะเก็บลำดับสมาชิก ใช้เป็น AUTO_INCREMENT
ฟิลด์ user_id จะใช้ ค่า id ด้านบนเข้ารหัสด้วย crypt() ในรูปแบบไม่ยาวเกินไป
ฟิลด์ name และ email ใช้เก็บค่าจาก social api หากมีข้อมูล
ฟิลด์ picture เราจะใช้เก็บชื่อรูปโพรไฟล์ โดยจะบันทึกรูปจาก url รูปโพรไฟล์ที่ได้จาก social api
ในทีนี้จะใช้วิธีการบันทึกด้วยรูปแบบง่าย โดยเก็บไฟล์ไว้ในโฟลเดอร์ avatar และใช้ชื่อรูปเป็นชื่อ
ตามค่าในฟิลด์ user_id ตามด้วยนามสกุลไฟล์
ฟิลด์ social_token จะใช้เก็บ userID ของบัญชีผู้ใช้นั้น โดยใช้วิธีแยก platform ด้วย ลำดับ ในที่นี้ใช้
01,02,03 และ 04 สำหรับ Line , Google , Facebook และ Twitter ตามลำดับ
เข้ารหัสด้วย md5() ซึ่งพอจะแปลงกลับและเอาไว้ใช้เช็คค่าได้ ต่อและคั่นด้วย "|" กับ userID ของผู้ใช้
ในบัญชีนั้นๆ เข้ารหัสด้วย crypt()
ฟิลด์นี้ เราจะใช้สำหรับล็อกอิน
ฟิลด์ create_date วันที่ขณะที่สมัคร ใช้เป็นค่าอัตโนมัติ ณ ขณะเวลานั้น
ฟิลด์ last_login วันที่ เวลา เข้าใช้งานล่าสุด
ฟิดล์อื่นๆ เพิ่มเติม หรือปรับตามต้องการ
สร้าง class สำหรับระบบสมัครสมาชิก
ต่อไปให้เราสร้างไฟล์ class ที่ชื่อ User.php ไว้ในโฟลเดอร์ socialconnect ไฟล์นี้ จะทำหน้าที่ในการตรวจสอบ
การสมัครสมาชิกใหม่กรณีใช้งานครั้งแรก และทำการล็อกอินด้วย Social Login ที่รองรับทุก platform คำอธิบาย
แสดงในโค้ด รูปแบบการใช้งานไม่ซับซ้อน
ไฟล์ User.php (ตัวพิมพ์ใหญ่ตัวแรก)
<?php class User{ // $salt สามารถใช้คำสั่ง password_hash("mysslweb",PASSWORD_BCRYPT); สร้างได้ private $_SALT = '$2y$10$cDKiRAzt3zWwiyAu/Nz40Om6yKe1mQZMM4T6yxAlTTI25oIUq9EVm'; private $_USER_DATA; private $_SOCIAL_TYPE; private $_DB; public function __construct($db, $userData, $socialType){ $this->_DB = $db; // รับค่า mysqli สำหรับจัดการฐานข้อมูล $this->_USER_DATA = $userData; $this->_SOCIAL_TYPE = $socialType; } public function login(){ $user = NULL; // จัดรูปแบบ Tokken ที่จะบันทึกลงฐานข้อมูล $checkToken = md5(sprintf("%02d",$this->_SOCIAL_TYPE))."|".$this->_USER_DATA['token']; $result = $this->_DB->query("SELECT * FROM tbl_user WHERE social_token='{$checkToken}' "); if($result && $result->num_rows>0){ // มีเราระบบแล้ว $row = $result->fetch_assoc(); // ฟิลด์ข้อมูลที่จะส่งกลับไปใช้ใน $_SESSION['ses_user'] เพิ่ม หรือแก้ไขฟิลด์ที่จะใช้ตามต้องการ $user = array( "id" => $row['user_id'], "name" => $row['name'], "email" => $row['email'], "picture" => $row['picture'], ); $last_login = date("Y-m-d H:i:s"); // อัพเดทเวลาเข้าใช้ล่าสุด $this->_DB->query(" UPDATE tbl_user SET last_login='{$last_login}' WHERE id='{$row['id']}' "); }else{ // ยังไม่มีในระบบ สมัครสมาชิก สร้างบัญชีผู้ใช้ใหม่ $user = $this->register($checkToken); } return $user; } public function getuser($id){ $result = $this->_DB->query("SELECT * FROM tbl_user WHERE id='{$id}' "); if($result && $result->num_rows>0){ $row = $result->fetch_assoc(); return $row; }else{ return; } } public function register($token){ // เพิ่มข้อมูลบัญชีผู้ใช้ใหม่ในระบบสมาชิก $result = $this->_DB->query(" INSERT INTO tbl_user SET name='{$this->_USER_DATA['name']}', email='{$this->_USER_DATA['email']}', social_token='{$token}' "); if($result && $this->_DB->affected_rows>0){ $insert_userID = $this->_DB->insert_id; // ลำดับ id ที่เพิ่มล่าสุด // นำลำดับ id ที่เพิ่มล่าสุดมาจัดรูปแบบ เพื่อสร้าง user_id เฉพาะ ของระบบสมาชิกของเรา $user_id = $this->removespecialchar(crypt(sprintf("%07d",$insert_userID),$this->_SALT)); // บันทึกรูปจาด url สร้างรูป avatar ใน servr ของเรา $avatar = $this->saveavatar($this->_USER_DATA['picture'],$user_id); $last_login = date("Y-m-d H:i:s"); // อัพเดทข้อมูลบัญชีเพิ่มเติม $this->_DB->query(" UPDATE tbl_user SET user_id='{$user_id}', picture='{$avatar}', last_login='{$last_login}' WHERE id='{$insert_userID}' "); // ดึงข้อมูลสมาชิก กรณีสมัคสมาชิกใหม่ $row = $this->getuser($insert_userID); if(isset($row)){ // ฟิลด์ข้อมูลที่จะส่งกลับไปใช้ใน $_SESSION['ses_user'] เพิ่ม หรือแก้ไขฟิลด์ที่จะใช้ตามต้องการ $user = array( "id" => $row['user_id'], "name" => $row['name'], "email" => $row['email'], "picture" => $row['picture'], ); return $user; } return; } } public function removespecialchar($value){ return preg_replace('/[^a-zA-Z0-9_ -]/s','',$value); } public function saveavatar($picture_url,$user_id){ $imgExt = array("1"=>".gif", "2"=>".jpg", "3"=>".png"); $imgType = exif_imagetype($picture_url); $avatar_filename = ""; try{ $endpontURL = $picture_url; $ch = curl_init(); curl_setopt( $ch, CURLOPT_URL, $endpontURL); curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec( $ch ); $avatar_filename = "{$user_id}".$imgExt[$imgType]; $filePath = "../avatar/{$avatar_filename}"; // บันทึกรูปไว้ที่โฟลเดอร์ avatar file_put_contents($filePath,$result); }finally{ curl_close( $ch ); } return $avatar_filename; } }
เมื่อเราเตรียมระบบจัดการสำหรับการสมัครสมาชิก และล็อกอินด้วย Social Platform เรียบร้อยแล้ว ต่อไปก็เป็นส่วน
ของการเรียกใช้งาน ซึ่งไม่ยุ่งยาก ปรับใช้กับแต่ละไฟล์ platform ได้ง่ายๆ โดยทำการเพิ่ม การเรียกใช้ การเชื่อมต่อ
กับ server ฐานข้อมูลผ่านไฟล์ dbconnect.php ไฟล์นี้จะได้ตัวแปร $mysqli ไปใช้งาน เรียกใช้ User class และ กำหนด
การตั้ง zone เวลาเพิ่มเติม หากจำเป็นต้องใช้ กรณี server เวลาไม่ตรง
จะได้ส่วนปรับเพิ่มเติม ของแต่ละ platform ดังนี้
ไฟล์ line.php
<?php session_start(); date_default_timezone_set("Asia/Bangkok"); // โค้ดไฟล์ dbconnect.php ดูได้ที่ http://niik.in/que_2398_5642 require_once('../dbconnect.php'); require_once('../vendor/autoload.php'); use Ninenik\LineOAuth\LineOAuth; require_once('./User.php'); class Socialconnect{ private $_LINE_CLIENT; // $salt สามารถใช้คำสั่ง password_hash("mysslweb",PASSWORD_BCRYPT); สร้างได้ private $_SALT = '$2y$10$cDKiRAzt3zWwiyAu/Nz40Om6yKe1mQZMM4T6yxAlTTI25oIUq9EVm'; // กำหนดค่าที่จะใช้งานในส่วนนี้ private $_CHANNEL_ID = "16xxxxx18x"; private $_CHANNEL_SECRET = "46xxx17feexxxxxxee47d"; private $_CHANNEL_CALLBACK = "https://www.mysslweb.com/socialconnect/line"; private $_DB; // ตัวแปรเชื่อมต่อฐานข้อมูล public function __construct($mysqli){ // รับ parameter การเชื่อมต่อฐานข้อมูล $this->_DB = $mysqli; $this->_LINE_CLIENT = new LineOAuth(); } public function redirect($url){ header("Location:{$url}"); exit; } public function line(){ $this->_LINE_CLIENT->setapp( $this->_CHANNEL_ID, $this->_CHANNEL_SECRET, $this->_CHANNEL_CALLBACK ); } public function connectline(){ $this->line(); $this->_LINE_CLIENT->authorize(); } public function authorizedline($success_url,$error_url){ if(isset($_GET['error'])){ $this->redirect($error_url); }else{ if(isset($_GET['code'])){ $this->line(); $dataToken = $this->_LINE_CLIENT->requestAccessToken($_GET, true); print_r($dataToken); if(array_key_exists('access_token',$dataToken)){ $accessToken = $dataToken['access_token']; } if(array_key_exists('id_token',$dataToken)){ $line_userdata = json_decode($dataToken['user'],true); // ค่า ID , name , picture ที่เราสามารถนำไปใช้ได้ $line_userID = $line_userdata['sub']; $line_userName = $line_userdata['name']; $line_email = $line_userdata['email']; $line_userPicture = $line_userdata['picture']; $hashed_token = crypt($line_userID,$this->_SALT); // เก็บค่าตัวแปร ที่จะส่งไปใช้ในระบบการล็อกอิน และสมัครสมาชิก $userData['id'] = (isset($line_userID))?$line_userID:null; $userData['name'] = (isset($line_userName))?$line_userName:null; $userData['email'] = (isset($line_email))?$line_email:null; $userData['picture'] = (isset($line_userPicture))?$line_userPicture:null; $userData['token'] = (isset($hashed_token))?$hashed_token:null; } if(isset($line_userID) && isset($hashed_token) && isset($accessToken)){ // เรียกใช้งาน User Class กำหนดตัวเลข ชนิดของ ประเภทของ social ที่ใช้งาน // Line , Google , Facebook และ Twitter จะเป็น 1,2,3 และ 4 ตามลำดับ $_USER = new User($this->_DB,$userData,1); $_SESSION['ses_user'] = $_USER->login(); // เรียกใช้งานคำสั่งสมัคร และล็อกอิน คืนค่า array ข้อมูลผู้ใช้ $this->redirect($success_url); }else{ $this->redirect($error_url); } }else{ $this->redirect($error_url); } } } } ?> <?php $social = new Socialconnect($mysqli); // ส่งการเชื่อมกับฐานข้อมูลเข้าไปใช้งาน if(isset($_GET['action']) && $_GET['action']=="connect"){ $social->connectline(); }else{ $social->authorizedline("../member.php","../login.php"); } ?>
ไฟล์ google.php
<?php session_start(); date_default_timezone_set("Asia/Bangkok"); // โค้ดไฟล์ dbconnect.php ดูได้ที่ http://niik.in/que_2398_5642 require_once('../dbconnect.php'); require_once('../vendor/autoload.php'); require_once('./User.php'); class Socialconnect{ private $_GOOGLE_CLIENT; // $salt สามารถใช้คำสั่ง password_hash("mysslweb",PASSWORD_BCRYPT); สร้างได้ private $_SALT = '$2y$10$cDKiRAzt3zWwiyAu/Nz40Om6yKe1mQZMM4T6yxAlTTI25oIUq9EVm'; // กำหนดค่าที่จะใช้งานในส่วนนี้ private $_CLIENT_ID = "108xxxxx53-0xxxo0a9qxxxxxxxfo4c155hg45i.apps.googleusercontent.com"; private $_CLIENT_SECRET = "ddBxxxkNWxxxxaMnxxhfk"; private $_CLIENT_CALLBACK = "https://www.mysslweb.com/socialconnect/google"; private $_DB; // ตัวแปรเชื่อมต่อฐานข้อมูล public function __construct($mysqli){ // รับ parameter การเชื่อมต่อฐานข้อมูล $this->_DB = $mysqli; $this->_GOOGLE_CLIENT = new Google_Client(); } public function redirect($url){ header("Location:{$url}"); exit; } public function google(){ //Set the OAuth 2.0 Client ID $this->_GOOGLE_CLIENT->setClientId($this->_CLIENT_ID); //Set the OAuth 2.0 Client Secret key $this->_GOOGLE_CLIENT->setClientSecret($this->_CLIENT_SECRET); $this->_GOOGLE_CLIENT->setRedirectUri($this->_CLIENT_CALLBACK); $this->_GOOGLE_CLIENT->addScope('email'); $this->_GOOGLE_CLIENT->addScope('profile'); } public function connectgoogle(){ $this->google(); $this->redirect($this->_GOOGLE_CLIENT->createAuthUrl()); } public function authorizedgoogle($success_url,$error_url){ if(isset($_GET['error'])){ $this->redirect($error_url); }else{ if(isset($_GET['code'])){ $this->google(); $dataToken = $this->_GOOGLE_CLIENT->fetchAccessTokenWithAuthCode($_GET['code']); if(!isset($dataToken['error'])){ $this->_GOOGLE_CLIENT->setAccessToken($dataToken['access_token']); $accessToken = $dataToken['access_token']; //Create Object of Google Service OAuth 2 class $google_service = new Google_Service_Oauth2($this->_GOOGLE_CLIENT); //Get user profile data from google $me = $google_service->userinfo->get(); $google_userdata = array(); $google_userID = $me->getId(); $google_email = $me->getEmail(); $google_name = $me->getName(); $google_picture = $me->getPicture(); $hashed_token = crypt($google_userID,$this->_SALT); // เก็บค่าตัวแปร ที่จะส่งไปใช้ในระบบการล็อกอิน และสมัครสมาชิก $userData['id'] = (isset($google_userID))?$google_userID:null; $userData['name'] = (isset($google_name))?$google_name:null; $userData['email'] = (isset($google_email))?$google_email:null; $userData['picture'] = (isset($google_picture))?$google_picture:null; $userData['token'] = (isset($hashed_token))?$hashed_token:null; } if(isset($google_userID) && isset($hashed_token) && isset($accessToken)){ // เรียกใช้งาน User Class กำหนดตัวเลข ชนิดของ ประเภทของ social ที่ใช้งาน // Line , Google , Facebook และ Twitter จะเป็น 1,2,3 และ 4 ตามลำดับ $_USER = new User($this->_DB,$userData,2); $_SESSION['ses_user'] = $_USER->login(); // เรียกใช้งานคำสั่งสมัคร และล็อกอิน คืนค่า array ข้อมูลผู้ใช้ $this->redirect($success_url); }else{ $this->redirect($error_url); } }else{ $this->redirect($error_url); } } } } ?> <?php $social = new Socialconnect($mysqli); // ส่งการเชื่อมกับฐานข้อมูลเข้าไปใช้งาน if(isset($_GET['action']) && $_GET['action']=="connect"){ $social->connectgoogle(); }else{ $social->authorizedgoogle("../member.php","../login.php"); } ?>
ไฟล์ facebook.php
<?php session_start(); date_default_timezone_set("Asia/Bangkok"); // โค้ดไฟล์ dbconnect.php ดูได้ที่ http://niik.in/que_2398_5642 require_once('../dbconnect.php'); require_once('../vendor/autoload.php'); require_once('./User.php'); class Socialconnect{ private $_FACEBOOK_CLIENT; // $salt สามารถใช้คำสั่ง password_hash("mysslweb",PASSWORD_BCRYPT); สร้างได้ private $_SALT = '$2y$10$cDKiRAzt3zWwiyAu/Nz40Om6yKe1mQZMM4T6yxAlTTI25oIUq9EVm'; // กำหนดค่าที่จะใช้งานในส่วนนี้ private $_APP_ID = "96xx5x0xxx4xx"; private $_APP_SECRET = "15xxxxfd86xx945xxb58xxxfaxx3"; private $_APP_CALLBACK = "https://www.mysslweb.com/socialconnect/facebook"; private $_DB; // ตัวแปรเชื่อมต่อฐานข้อมูล public function __construct($mysqli){ // รับ parameter การเชื่อมต่อฐานข้อมูล $this->_DB = $mysqli; $this->_FACEBOOK_CLIENT = $this->facebook(); } public function redirect($url){ header("Location:{$url}"); exit; } public function facebook(){ return new \Facebook\Facebook([ 'app_id' => $this->_APP_ID, 'app_secret' => $this->_APP_SECRET, 'default_graph_version' => 'v7.0', //'default_access_token' => '{access-token}', // optional ]); } public function connectfacebook(){ $helper = $this->_FACEBOOK_CLIENT->getRedirectLoginHelper(); $permissions = ['email,public_profile']; // Optional permissions $loginUrl = $helper->getLoginUrl($this->_APP_CALLBACK, $permissions); $this->redirect($loginUrl); } public function authorizedfacebook($success_url,$error_url){ echo "<pre>"; print_r($_GET); // exit; if(isset($_GET['error'])){ $this->redirect($error_url); }else{ if(isset($_GET['code'])){ $helper = $helper = $this->_FACEBOOK_CLIENT->getRedirectLoginHelper(); try { $accessToken = $helper->getAccessToken(); } catch(\Facebook\Exceptions\FacebookResponseException $e) { // When Graph returns an error $this->redirect($error_url); } catch(\Facebook\Exceptions\FacebookSDKException $e) { // When validation fails or other local issues $this->redirect($error_url); } if (isset($accessToken)) { $response = $this->_FACEBOOK_CLIENT->get('/me?fields=id,name,email,picture', $accessToken); $profile_picture = $this->_FACEBOOK_CLIENT->get('/me/picture?type=large', $accessToken); $me = $response->getGraphUser(); $picture = $profile_picture->getHeaders(); $fb_userID = $me->getId(); $fb_name = $me->getName(); $fb_email = $me->getEmail(); $fb_picture = $me->getPicture(); $hashed_token = crypt($fb_userID, $this->_SALT); // เก็บค่าตัวแปร ที่จะส่งไปใช้ในระบบการล็อกอิน และสมัครสมาชิก $userData['id'] = (isset($fb_userID))?$fb_userID:null; $userData['name'] = (isset($fb_name))?$fb_name:null; $userData['email'] = (isset($fb_email))?$fb_email:null; $userData['picture'] = (isset($picture['location']))?$picture['location']:null; $userData['token'] = (isset($hashed_token))?$hashed_token:null; } if(isset($fb_userID) && isset($hashed_token) && isset($accessToken)){ // เรียกใช้งาน User Class กำหนดตัวเลข ชนิดของ ประเภทของ social ที่ใช้งาน // Line , Google , Facebook และ Twitter จะเป็น 1,2,3 และ 4 ตามลำดับ $_USER = new User($this->_DB,$userData,3); $_SESSION['ses_user'] = $_USER->login(); // เรียกใช้งานคำสั่งสมัคร และล็อกอิน คืนค่า array ข้อมูลผู้ใช้ $this->redirect($success_url); }else{ $this->redirect($error_url); } }else{ $this->redirect($error_url); } } } } ?> <?php $social = new Socialconnect($mysqli); // ส่งการเชื่อมกับฐานข้อมูลเข้าไปใช้งาน if(isset($_GET['action']) && $_GET['action']=="connect"){ $social->connectfacebook(); }else{ $social->authorizedfacebook("../member.php","../login.php"); } ?>
ไฟล์ twitter.php
<?php session_start(); date_default_timezone_set("Asia/Bangkok"); // โค้ดไฟล์ dbconnect.php ดูได้ที่ http://niik.in/que_2398_5642 require_once('../dbconnect.php'); require_once('../vendor/autoload.php'); use Abraham\TwitterOAuth\TwitterOAuth; require_once('./User.php'); class Socialconnect{ private $_TWITTER_CLIENT; // $salt สามารถใช้คำสั่ง password_hash("mysslweb",PASSWORD_BCRYPT); สร้างได้ private $_SALT = '$2y$10$cDKiRAzt3zWwiyAu/Nz40Om6yKe1mQZMM4T6yxAlTTI25oIUq9EVm'; // กำหนดค่าที่จะใช้งานในส่วนนี้ private $_API_KEY = "nMxxgxxxxIP79UiJKDafxxxob"; private $_API_SECRET = "UUxxxOWpRIOexxxxIenBxxx4KeYQxxxicKKptayYikz"; private $_API_CALLBACK = "https://www.mysslweb.com/socialconnect/twitter"; private $_DB; // ตัวแปรเชื่อมต่อฐานข้อมูล public function __construct($mysqli){ // รับ parameter การเชื่อมต่อฐานข้อมูล $this->_DB = $mysqli; $this->_TWITTER_CLIENT = $this->twitter(); } public function redirect($url){ header("Location:{$url}"); exit; } public function twitter($token=null,$token_secret=null){ return new TwitterOAuth( $this->_API_KEY, $this->_API_SECRET, $token, $token_secret); } public function connecttwitter(){ $callback_url = $this->_API_CALLBACK; $request_token = $this->_TWITTER_CLIENT->oauth('oauth/request_token', array('oauth_callback' => $callback_url)); $_SESSION['oauth_token'] = $request_token['oauth_token']; $_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret']; $authUrl = $this->_TWITTER_CLIENT->url('oauth/authorize', array('oauth_token' => $request_token['oauth_token'])); $this->redirect($authUrl); } public function authorizedtwitter($success_url,$error_url){ if(isset($_GET['denied'])){ $this->redirect($error_url); }else{ if(isset($_GET['oauth_verifier'])){ try{ $this->_TWITTER_CLIENT = $this->twitter($_SESSION['oauth_token'],$_SESSION['oauth_token_secret']); $access_token = $this->_TWITTER_CLIENT->oauth("oauth/access_token", ["oauth_verifier" => $_GET['oauth_verifier']]); }catch(\Abraham\TwitterOAuth\TwitterOAuthException $e){ $this->redirect($error_url); } if(isset($access_token['oauth_token']) && isset($access_token['oauth_token_secret']) ){ $this->_TWITTER_CLIENT = $this->twitter($access_token['oauth_token'], $access_token['oauth_token_secret']); $me = $this->_TWITTER_CLIENT->get('account/verify_credentials',['include_email' => true]); $accessToken = $access_token['oauth_token']; $twitter_userdata = array(); $twitter_userdata['picture'] = str_replace("normal","400x400",$me->profile_image_url_https); $twitter_userID = $me->id; $twitter_name = $me->name; $twitter_email = (isset($me->email))?$me->email:null; $twitter_picture =$twitter_userdata['picture']; $hashed_token = crypt($twitter_userID, $this->_SALT); // เก็บค่าตัวแปร ที่จะส่งไปใช้ในระบบการล็อกอิน และสมัครสมาชิก $userData['id'] = (isset($twitter_userID))?$twitter_userID:null; $userData['name'] = (isset($twitter_name))?$twitter_name:null; $userData['email'] = (isset($twitter_email))?$twitter_email:null; $userData['picture'] = (isset($twitter_picture))?$twitter_picture:null; $userData['token'] = (isset($hashed_token))?$hashed_token:null; }else{ $this->redirect($error_url); } if(isset($twitter_userID) && isset($hashed_token) && isset($accessToken)){ // เรียกใช้งาน User Class กำหนดตัวเลข ชนิดของ ประเภทของ social ที่ใช้งาน // Line , Google , Facebook และ Twitter จะเป็น 1,2,3 และ 4 ตามลำดับ $_USER = new User($this->_DB,$userData,4); $_SESSION['ses_user'] = $_USER->login(); // เรียกใช้งานคำสั่งสมัคร และล็อกอิน คืนค่า array ข้อมูลผู้ใช้ $this->redirect($success_url); }else{ $this->redirect($error_url); } }else{ $this->redirect($error_url); } } } } ?> <?php $social = new Socialconnect($mysqli); // ส่งการเชื่อมกับฐานข้อมูลเข้าไปใช้งาน if(isset($_GET['action']) && $_GET['action']=="connect"){ $social->connecttwitter(); }else{ $social->authorizedtwitter("../member.php","../login.php"); } ?>
ดูส่วนที่ปรับจากตอนที่ 2 ในบรรทัดที่ได้ highlight ไว้
เราอาจจะทดสอบแสดงข้อมูลในหน้า member โดยเพิ่มโค้ดเล็กน้อยนี้ลงไปได้
<h4><?=$_SESSION['ses_user']['name']?></h4> <img src="avatar/<?=$_SESSION['ses_user']['picture']?>" style="width: 50px;"> </div>
เป็นอันเสร็จเรียบร้อย กับการสร้างระบบสมาชิกด้วยบัญชีผู้ใช้ Social ข้อมูลจะถูกบันทึกในตารางฐานข้อมูล
เป็นข้อมูลที่ถูกเข้ารหัสไว้ในเบื้องต้น แต่ยังสามารถอ้างอิงการใช้งานข้อมูลได้ โดยรูปแบบเป็นไปตามที่ได้กล่าวไว้
สมาชิกแต่ละ platform จะถูกสร้างเป็นบัญชีผู้ใช้ใหม่ ครั้งแรกที่ใช้งาน
สามารถดูตัวอย่างได้ที่ DEMO 1 ด้านล่าง
สำหรับแบบที่สอง การเชื่อมโยงบัญชีผู้ใช้ หรือระบบสมาชิกเดิมของเราที่มีอยู่แล้ว จะขอยกไปเปฺ็นเนื้อาในตอนที่ 4
เพื่อที่จะได้แยกทำความเข้าใจได้ง่ายขึ้น รอติดตาม