├── README.md ├── demo.ogv └── screenshots ├── add_new_app.png ├── demo_step_1.png ├── demo_step_2_1.png ├── demo_step_2_2.png ├── demo_step_3.png ├── demo_step_4.png ├── demo_step_5.png ├── install_discuz.png ├── install_uc.png └── tree.png /README.md: -------------------------------------------------------------------------------- 1 | # CodeIgniter 整合 UCenter 全攻略 2 | 3 | > 本文默认你已详细阅读过 UCcenter 官方手册并对 CodeIgniter 有一定的了解。 4 | 5 | ## 下载相应的软件 6 | 7 | * [CodeIgniter 2.1.4](http://codeigniter.org.cn/download) 8 | * [Ucenter 1.6.0](http://www.comsenz.com/downloads/install/ucenter#down_open) 9 | * [Discuz! X3](http://www.comsenz.com/downloads/install/discuzx) 10 | 11 | 简体 UTF-8,可以不下载 Discuz!,这里只是用来最后检验同步登录/登出是否成功。 12 | 13 | ## 前置条件 14 | 15 | - 项目目录结构如下 16 | 17 | ![image](screenshots/tree.png) 18 | 19 | 20 | - 搭建服务器 21 | 22 | 根目录指向 codeIgniter-ucenter 23 | 24 | 我设置了 hosts 25 | 26 | ``` 27 | 127.0.0.1 ci.connect.uc 28 | ``` 29 | 30 | 这个任意的,这里只是为了突出主题. 31 | 32 | ## 开始集成 33 | 34 | - 安装 UCenter 35 | 36 | 访问 http://ci.connect.uc/uc ,按照向导安装即可。 37 | 38 | ![image](screenshots/install_uc.png) 39 | 40 | - 安装 DiscuzX 41 | 42 | 访问 http://ci.connect.uc/discuz ,按照向导,第二步时候选择只安装DiscuzX,如下图,信息填写 UCenter 的安装信息。 43 | 44 | ![image](screenshots/install_discuz.png) 45 | 46 | - 配置 CodeIgniter 47 | 48 | * 配置 application/config.php, 为使用 Session 类,需要设置 encryption_key,值任意。 49 | 50 | ``` 51 | $config['encryption_key'] = sha1('whatever it is!'); 52 | ``` 53 | 54 | * 修改默认控制器 welcome.php 如下: 55 | 56 | ```php 57 | 58 | load->library('session'); 65 | $data['user'] = $this->session->userdata('user'); 66 | $this->load->view('welcome_message', $data); 67 | } 68 | } 69 | 70 | ``` 71 | 72 | * 修改views/welcome_message.php中的 **div#container** 如下: 73 | 74 | ```html 75 | 76 |
77 |

Welcome to CodeIgniter!

78 |
79 | 80 |

欢迎你, DiscuzX退出后再刷新这个页面吧!

81 | 82 |

尚未登录,到DiscuzX登录后再刷新这个页面吧!

83 | 84 |
85 | 86 |
87 | 88 | ``` 89 | 90 | * 在Ucenter中添加新应用 91 | 92 | 看图: 93 | ![image](screenshots/add_new_app.png) 94 | 95 | * 在CI目录application/config/目录下新建文件ucenter.php 96 | 97 | 内容为Ucenter为新加应用生成的配置文件 98 | 99 | ```php 100 | 101 | 136 | */ 137 | 138 | class Uc extends CI_Controller 139 | { 140 | const UC_CLIENT_RELEASE = '20110501'; 141 | const UC_CLIENT_VERSION = '1.6.0'; 142 | 143 | const API_DELETEUSER = 1; 144 | const API_RENAMEUSER = 1; 145 | const API_GETTAG = 1; 146 | const API_SYNLOGIN = 1; 147 | const API_SYNLOGOUT = 1; 148 | const API_UPDATEPW = 1; 149 | const API_UPDATEBADWORDS = 1; 150 | const API_UPDATEHOSTS = 1; 151 | const API_UPDATEAPPS = 1; 152 | const API_UPDATECLIENT = 1; 153 | const API_UPDATECREDIT = 1; 154 | const API_GETCREDITSETTINGS = 1; 155 | const API_GETCREDIT = 1; 156 | const API_UPDATECREDITSETTINGS = 1; 157 | 158 | const API_RETURN_SUCCEED = 1; 159 | const API_RETURN_FAILED = -1; 160 | const API_RETURN_FORBIDDEN = -2; 161 | 162 | public function index() 163 | { 164 | include APPPATH.'config/ucenter.php'; 165 | $get = $post = array(); 166 | $code = $this->input->get('code', true); 167 | parse_str(self::authcode($code, 'DECODE', UC_KEY), $get); 168 | $timestamp = time(); 169 | if ($timestamp - $get['time'] > 3600) 170 | { 171 | echo '授权已过期'; 172 | return; 173 | } 174 | if (empty($get)) 175 | { 176 | echo '非法请求'; 177 | return; 178 | } 179 | $post = self::unserialize(file_get_contents('php://input')); 180 | if (in_array($get['action'], array( 181 | 'test', 182 | 'deleteuser', 183 | 'renameuser', 184 | 'gettag', 185 | 'synlogin', 186 | 'synlogout', 187 | 'updatepw', 188 | 'updatebadwords', 189 | 'updatehosts', 190 | 'updateapps', 191 | 'updateclient', 192 | 'updatecredit', 193 | 'getcreditsettings', 194 | 'updatecreditsettings'))) 195 | { 196 | 197 | echo $this->$get['action']($get, $post); 198 | return; 199 | } 200 | else 201 | { 202 | echo self::API_RETURN_FAILED; 203 | return; 204 | } 205 | 206 | } 207 | 208 | private function test($get, $post) 209 | { 210 | return self::API_RETURN_SUCCEED; 211 | } 212 | 213 | private function deleteuser($get, $post) 214 | { 215 | if ( ! self::API_DELETEUSER) 216 | { 217 | return self::API_RETURN_FORBIDDEN; 218 | } 219 | $uids = $get['ids']; 220 | //delete your users here 221 | return self::API_RETURN_SUCCEED; 222 | } 223 | 224 | private function gettag($get, $post) 225 | { 226 | if ( ! self::API_GETTAG) 227 | { 228 | return self::API_RETURN_FORBIDDEN; 229 | } 230 | // 231 | return self::API_RETURN_SUCCEED; 232 | } 233 | 234 | private function synlogin($get, $post) 235 | { 236 | if ( ! self::API_SYNLOGIN) 237 | { 238 | return self::API_RETURN_FORBIDDEN; 239 | } 240 | header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"'); 241 | $uid = $get['uid']; 242 | //同步登录的代码在这里处理 243 | include APPPATH.'../uc_client/client.php'; 244 | if ($uc_user = uc_get_user($uid, 1)) 245 | { 246 | $this->load->library('session'); 247 | $this->session->set_userdata('user', array( 248 | 'uid' => $uid, 249 | 'username' => $uc_user[1] 250 | )); 251 | } 252 | 253 | return self::API_RETURN_SUCCEED; 254 | } 255 | 256 | private function synlogout($get, $post) 257 | { 258 | if ( ! self::API_SYNLOGOUT) 259 | { 260 | return self::API_RETURN_FORBIDDEN; 261 | } 262 | header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"'); 263 | $this->load->library('session'); 264 | $this->session->sess_destroy(); 265 | return self::API_RETURN_SUCCEED; 266 | } 267 | 268 | private function updatepw($get, $post) 269 | { 270 | if ( ! self::API_UPDATEPW) 271 | { 272 | return self::API_RETURN_FORBIDDEN; 273 | } 274 | //这里做修改密码操作 275 | return self::API_RETURN_SUCCEED; 276 | } 277 | 278 | private function updatebadwords($get, $post) 279 | { 280 | if ( ! self::API_UPDATEBADWORDS) 281 | { 282 | return self::API_RETURN_FORBIDDEN; 283 | } 284 | $cachefile = APPPATH.'../uc_client/data/cache/badwords.php'; 285 | @unlink($cachefile); 286 | return self::API_RETURN_SUCCEED; 287 | } 288 | 289 | private function updatehosts($get, $post) 290 | { 291 | if ( ! self::API_UPDATEHOSTS) 292 | { 293 | return self::API_RETURN_FORBIDDEN; 294 | } 295 | $cachefile = APPPATH.'../uc_client/data/cache/hosts.php'; 296 | @unlink($cachefile); 297 | return self::API_RETURN_SUCCEED; 298 | } 299 | 300 | private function updateapps($get, $post) 301 | { 302 | if ( ! self::API_UPDATEAPPS) 303 | { 304 | return self::API_RETURN_FORBIDDEN; 305 | } 306 | $cachefile = APPPATH.'../uc_client/data/cache/apps.php'; 307 | @unlink($cachefile); 308 | return self::API_RETURN_SUCCEED; 309 | } 310 | 311 | private function updateclient($get, $post) 312 | { 313 | if ( ! self::API_UPDATECLIENT) 314 | { 315 | return self::API_RETURN_FORBIDDEN; 316 | } 317 | $cachefile = APPPATH.'../uc_client/data/cache/settings.php'; 318 | @unlink($cachefile); 319 | return self::API_RETURN_SUCCEED; 320 | } 321 | 322 | private function updatecredit($get, $post) 323 | { 324 | if ( ! self::API_UPDATECREDIT) 325 | { 326 | return self::API_RETURN_FORBIDDEN; 327 | } 328 | return self::API_RETURN_SUCCEED; 329 | } 330 | 331 | private function getcredit($get, $post) 332 | { 333 | if ( ! self::API_GETCREDIT) 334 | { 335 | return self::API_RETURN_FORBIDDEN; 336 | } 337 | return self::API_RETURN_SUCCEED; 338 | } 339 | 340 | public static function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) 341 | { 342 | $ckey_length = 4; 343 | $key = md5($key ? $key : UC_KEY); 344 | $keya = md5(substr($key, 0, 16)); 345 | $keyb = md5(substr($key, 16, 16)); 346 | $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : ''; 347 | 348 | $cryptkey = $keya.md5($keya.$keyc); 349 | $key_length = strlen($cryptkey); 350 | 351 | $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string; 352 | $string_length = strlen($string); 353 | 354 | $result = ''; 355 | $box = range(0, 255); 356 | 357 | $rndkey = array(); 358 | for($i = 0; $i <= 255; $i++) 359 | { 360 | $rndkey[$i] = ord($cryptkey[$i % $key_length]); 361 | } 362 | 363 | for($j = $i = 0; $i < 256; $i++) 364 | { 365 | $j = ($j + $box[$i] + $rndkey[$i]) % 256; 366 | $tmp = $box[$i]; 367 | $box[$i] = $box[$j]; 368 | $box[$j] = $tmp; 369 | } 370 | 371 | for($a = $j = $i = 0; $i < $string_length; $i++) 372 | { 373 | $a = ($a + 1) % 256; 374 | $j = ($j + $box[$a]) % 256; 375 | $tmp = $box[$a]; 376 | $box[$a] = $box[$j]; 377 | $box[$j] = $tmp; 378 | $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); 379 | } 380 | 381 | if($operation == 'DECODE') 382 | { 383 | if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) 384 | { 385 | return substr($result, 26); 386 | } 387 | else 388 | { 389 | return ''; 390 | } 391 | } 392 | else 393 | { 394 | return $keyc.str_replace('=', '', base64_encode($result)); 395 | } 396 | } 397 | 398 | public static function serialize($arr, $htmlOn = 0) 399 | { 400 | if ( ! function_exists('xml_serialize')) 401 | { 402 | require APPPATH.'../uc_client/lib/xml.class.php'; 403 | } 404 | return xml_serialize($arr, $htmlOn); 405 | } 406 | 407 | public static function unserialize($xml, $htmlOn = 0) 408 | { 409 | if ( ! function_exists('xml_serialize')) 410 | { 411 | require APPPATH.'../uc_client/lib/xml.class.php'; 412 | } 413 | return xml_unserialize($xml, $htmlOn); 414 | } 415 | 416 | public static function gbk2utf8($string) 417 | { 418 | return iconv("GB2312", "UTF-8//IGNORE", $string); 419 | } 420 | 421 | public static function utf82gbk($string) 422 | { 423 | return iconv("UTF-8", "GB2312//IGNORE", $string); 424 | } 425 | 426 | } 427 | 428 | ``` 429 | 430 | ## 运行 431 | 432 | 433 | * 打开 http://ci.connect.uc/ci 434 | 435 | ![image](screenshots/demo_step_1.png) 436 | 437 | * 点击页面链接进行登录操作 438 | 439 | ![image](screenshots/demo_step_2_1.png) 440 | 441 | ![image](screenshots/demo_step_2_2.png) 442 | 443 | * 刷新即可看到已登录 444 | 445 | ![image](screenshots/demo_step_3.png) 446 | 447 | * 点击页面链接进行退出操作 448 | 449 | ![image](screenshots/demo_step_4.png) 450 | 451 | * 再次刷新即可看到已退出 452 | 453 | ![image](screenshots/demo_step_5.png) 454 | 455 | > 你还可以打开 demo.ogv 来观看演示程序的运行视频。 456 | 457 | 458 | 459 | 460 | 本教程不含自带用户数据库的情况下,在自有用户表的情况下,处理逻辑类似,要有一个字段记录 UCenter 的唯一用户 ID,同步登录和退出的逻辑里使用该 ID 进行相应的操作。 461 | 462 | 有任何问题请发 issues。 463 | -------------------------------------------------------------------------------- /demo.ogv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeIgniter-Chinese/ucenter-how-to/f7d26cd5851bdd23695325d093d161203c815bd6/demo.ogv -------------------------------------------------------------------------------- /screenshots/add_new_app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeIgniter-Chinese/ucenter-how-to/f7d26cd5851bdd23695325d093d161203c815bd6/screenshots/add_new_app.png -------------------------------------------------------------------------------- /screenshots/demo_step_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeIgniter-Chinese/ucenter-how-to/f7d26cd5851bdd23695325d093d161203c815bd6/screenshots/demo_step_1.png -------------------------------------------------------------------------------- /screenshots/demo_step_2_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeIgniter-Chinese/ucenter-how-to/f7d26cd5851bdd23695325d093d161203c815bd6/screenshots/demo_step_2_1.png -------------------------------------------------------------------------------- /screenshots/demo_step_2_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeIgniter-Chinese/ucenter-how-to/f7d26cd5851bdd23695325d093d161203c815bd6/screenshots/demo_step_2_2.png -------------------------------------------------------------------------------- /screenshots/demo_step_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeIgniter-Chinese/ucenter-how-to/f7d26cd5851bdd23695325d093d161203c815bd6/screenshots/demo_step_3.png -------------------------------------------------------------------------------- /screenshots/demo_step_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeIgniter-Chinese/ucenter-how-to/f7d26cd5851bdd23695325d093d161203c815bd6/screenshots/demo_step_4.png -------------------------------------------------------------------------------- /screenshots/demo_step_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeIgniter-Chinese/ucenter-how-to/f7d26cd5851bdd23695325d093d161203c815bd6/screenshots/demo_step_5.png -------------------------------------------------------------------------------- /screenshots/install_discuz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeIgniter-Chinese/ucenter-how-to/f7d26cd5851bdd23695325d093d161203c815bd6/screenshots/install_discuz.png -------------------------------------------------------------------------------- /screenshots/install_uc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeIgniter-Chinese/ucenter-how-to/f7d26cd5851bdd23695325d093d161203c815bd6/screenshots/install_uc.png -------------------------------------------------------------------------------- /screenshots/tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeIgniter-Chinese/ucenter-how-to/f7d26cd5851bdd23695325d093d161203c815bd6/screenshots/tree.png --------------------------------------------------------------------------------