You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
5.3 KiB

7 years ago
  1. <?php
  2. defined('BASEPATH') OR exit('No direct script access allowed');
  3. class Social_login {
  4. protected $CI;
  5. protected $social_provider;
  6. protected $social_setting;
  7. function __construct()
  8. {
  9. $this->CI =& get_instance();
  10. $this->CI->load->helper('url');
  11. $this->CI->load->library('session');
  12. $this->social_provider = strtolower(get_called_class());
  13. $this->social_setting = new stdClass();
  14. $this->social_setting->client_id = NULL;
  15. $this->social_setting->client_secret = NULL;
  16. $this->social_setting->redirect_url = NULL;
  17. $this->social_setting->authorize_url = NULL;
  18. $this->social_setting->token_url = NULL;
  19. $this->social_setting->info_url = NULL;
  20. $this->social_setting->token_request_post = NULL;
  21. }
  22. function get_profile()
  23. {
  24. if( empty($this->social_provider) OR empty($this->social_setting->client_id) )
  25. {
  26. return FALSE;
  27. }
  28. if($code = $this->CI->input->get("code", TRUE) )
  29. {
  30. // AccessToken을 요청하고 받은값이 없으면 종료
  31. if(! $access_token_array = $this->_get_access_token($code) ) exit("Failed to get Access Token");
  32. if( isset($access_token_array['error']) && $access_token_array['error'] ) {
  33. exit("Failed to get Access Token : ".$access_token_array['error']);
  34. }
  35. if(! $profile = $this->_get_info($access_token_array['access_token'])) exit("Failed to get User Info");
  36. return $this->_generate_profile($profile);
  37. }
  38. else
  39. {
  40. if( $error = $this->CI->input->get('error', TRUE) )
  41. {
  42. // 코드를 받지 못한상태인데 Error GET값이 잇을경우
  43. echo "error : " . $this->CI->input->get('error', TRUE) . PHP_EOL;
  44. echo "error_descrption : ". $this->CI->input->get('error_description', TRUE);
  45. exit();
  46. }
  47. // oAuth 인증코드를 받지못한경우
  48. // 로그인 처리후 이동할 페이지를 세션으로 저장해 둡니다.
  49. $reurl = $this->CI->input->get('reurl', TRUE) ? $this->CI->input->get('reurl', TRUE) : base_url();
  50. $this->CI->session->set_userdata('reurl', $reurl);
  51. // oAuth Code를 받기위해 이동한다.
  52. $this->_redirect_authorize();
  53. }
  54. }
  55. protected function _generate_profile($profile)
  56. {
  57. return $profile;
  58. }
  59. /**
  60. * oAuth 코드를 받아올때 필요한 패러미터를 가져온다.
  61. */
  62. protected function _get_authorize_param() {
  63. $param = array();
  64. $param['response_type'] = "code";
  65. $param['client_id'] = $this->social_setting->client_id;
  66. $param['redirect_uri'] = $this->social_setting->redirect_url;
  67. return $param;
  68. }
  69. /**
  70. * Access Token 얻기위해 넘겨야할 패러미터를 가져온다.
  71. */
  72. protected function _get_token_param($code) {
  73. $param = array();
  74. $param['grant_type'] = "authorization_code";
  75. $param['code'] = $code;
  76. $param['state'] = $this->CI->session->userdata($this->social_provider."_state");
  77. $param['client_id'] = $this->social_setting->client_id;
  78. $param['client_secret'] = $this->social_setting->client_secret;
  79. $param['redirect_uri'] = $this->social_setting->redirect_url;
  80. return $param;
  81. }
  82. /**
  83. * oAuth 인증절차
  84. */
  85. protected function _redirect_authorize()
  86. {
  87. // State 값을 만들고, Session에 저장해둡니다.
  88. $state = md5(microtime().mt_rand());
  89. $this->CI->session->set_userdata( $this->social_provider."_state", $state);
  90. // 만든 State 값을 parameter에 추가한다.
  91. $param = $this->_get_authorize_param();
  92. $param['state'] = $state;
  93. // 요청 페이지 고고씽
  94. redirect($this->social_setting->authorize_url.'?'.http_build_query($param));
  95. exit;
  96. }
  97. /**
  98. * Curl을 통해 AccessToken을 얻어옵니다.
  99. */
  100. protected function _get_access_token($code)
  101. {
  102. $param = $this->_get_token_param($code);
  103. $this->social_setting->token_url .= ( $this->social_setting->token_request_post ) ? '':'?'.http_build_query($param);
  104. $ch = curl_init();
  105. curl_setopt ($ch, CURLOPT_URL, $this->social_setting->token_url);
  106. curl_setopt ($ch, CURLOPT_POST, $this->social_setting->token_request_post);
  107. if( $this->social_setting->token_request_post )
  108. {
  109. curl_setopt ($ch, CURLOPT_POSTFIELDS, http_build_query($param));
  110. }
  111. curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE);
  112. $result = curl_exec ($ch);
  113. $result_json = json_decode($result, TRUE);
  114. return $result_json;
  115. }
  116. /**
  117. * 사용자 프로필 조회요청
  118. */
  119. protected function _get_info($access_token, $add_param="")
  120. {
  121. if(empty($access_token) OR ! $access_token) return FALSE;
  122. $url = $this->social_setting->info_url.$add_param;
  123. $header = array("Authorization: Bearer {$access_token}");
  124. $ch = curl_init();
  125. curl_setopt ($ch, CURLOPT_URL, $url);
  126. curl_setopt ($ch, CURLOPT_HTTPHEADER, $header);
  127. curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
  128. $result = curl_exec($ch);
  129. return $result;
  130. }
  131. }