Discuz的passport与其他登录系统的整合
Submitted by Nichael on 2007-11-13 4:27 PM. Discuz学习
源贴地址:http://www.zjnch.cn/blog/?action=show&id=24
PHP代码
- <?php
- $path_bbs="upload/"; //bbs的相对路径地址
- $check_username="admin"; //测试用的用户名和密码,简单测试用,可以从数据库中读取,这里只是简单的测试
- $check_password="admin";
- if(@$_GET['action']=="logout") //用户退出,清楚cookie
- {
- setcookie('username','',time() - 3600);
- $username = "admin";
- $pwd = "admin";
- $member = array //menber数组,传递给dz论坛,必填的为time、username、password、email,没填则会报错,同时假如论坛数据
- ( //库中没有该记录,直接插入论坛用户表中,如果有则更新表中该用户信息
- 'cookietime' => time(),
- 'time' => time(),
- 'username' => $username,
- 'password' => md5($pwd),
- 'email' => 'abcd@efgh.com',
- );
- $passport_key = "ffffffffffff"; //dz后台系统设置中的密钥
- $action = 'logout';
- $forward = "http://localhost/www/discuz/upload/"; //重定向地址,告诉dz登录以后重定向到该地址
- $auth = passport_encrypt(passport_encode($member), $passport_key); //利用dz函数passport_encrypt对信息进行加密再传递给passport.php
- $verify = md5($action.$auth.$forward.$passport_key);
- header("Location: http://localhost/www/discuz/upload/api/passport.php"."?action=$action"."&auth=".rawurlencode($auth)."&forward=".rawurlencode($forward)."&verify=$verify"); //将参数传递给passport.php,必须以这种格式.
- }
- if(isset($_POST["submit"])) //登录判断,原理跟用户推出差不多
- {
- $username=trim($_POST['username']);
- $pwd=trim($_POST['password']);
- setcookie('username',$username);
- $member = array
- (
- 'cookietime' => time(),
- 'time' => time(),
- 'username' => $username,
- 'password' => md5($pwd),
- 'email' => 'abcd@efgh.com',
- );
- $passport_key = "ffffffffffff";
- $action = 'login';
- $forward = "http://localhost/www/discuz/login.php";
- $auth = passport_encrypt(passport_encode($member), $passport_key);
- $verify = md5($action.$auth.$forward.$passport_key);
- if($username==$check_username && $pwd==$check_password)
- {
- header("Location: http://localhost/www/discuz/upload/api/passport.php"."?action=$action"."&auth=".rawurlencode($auth)."&forward=".rawurlencode($forward)."&verify=$verify");
- }
- }
- ?>
- <?php
- if(@$_COOKIE['username']==''){
- ?>
- <form action="" method="POST">
- 用户名:<input name="username">测试用户名为admin<br>
- 密码:<input type="password" name="password">测试密码为admin<br>
- <input type="submit" name="submit" value="测试">
- </form>
- <?php
- }
- else echo("登陆成功,<a href='{$path_bbs}index.php' target=_blank>请到论坛检查登陆</a><br><a href='?act=logout'>退出登陆</a> ");
- ?>
- <?php
- /**
- * Passport 加密函数
- *
- * @param string 等待加密的原字串
- * @param string 私有密匙(用于解密和加密)
- *
- * @return string 原字串经过私有密匙加密后的结果
- */
- function passport_encrypt($txt, $key) {
- // 使用随机数发生器产生 0~32000 的值并 MD5()
- srand((double)microtime() * 1000000);
- $encrypt_key = md5(rand(0, 32000));
- // 变量初始化
- $ctr = 0;
- $tmp = '';
- // for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
- for($i = 0; $i < strlen($txt); $i++) {
- // 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
- $ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
- // $tmp 字串在末尾增加两位,其第一位内容为 $encrypt_key 的第 $ctr 位,
- // 第二位内容为 $txt 的第 $i 位与 $encrypt_key 的 $ctr 位取异或。然后 $ctr = $ctr + 1
- $tmp .= $encrypt_key[$ctr].($txt[$i] ^ $encrypt_key[$ctr++]);
- }
- // 返回结果,结果为 passport_key() 函数返回值的 base64 编码结果
- return base64_encode(passport_key($tmp, $key));
- }
- /**
- * Passport 解密函数
- *
- * @param string 加密后的字串
- * @param string 私有密匙(用于解密和加密)
- *
- * @return string 字串经过私有密匙解密后的结果
- */
- function passport_decrypt($txt, $key) {
- // $txt 的结果为加密后的字串经过 base64 解码,然后与私有密匙一起,
- // 经过 passport_key() 函数处理后的返回值
- $txt = passport_key(base64_decode($txt), $key);
- // 变量初始化
- $tmp = '';
- // for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
- for ($i = 0; $i < strlen($txt); $i++) {
- // $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
- // 与 $txt 的第 $i + 1 位取异或。然后 $i = $i + 1
- $tmp .= $txt[$i] ^ $txt[++$i];
- }
- // 返回 $tmp 的值作为结果
- return $tmp;
- }
- /**
- * Passport 密匙处理函数
- *
- * @param string 待加密或待解密的字串
- * @param string 私有密匙(用于解密和加密)
- *
- * @return string 处理后的密匙
- */
- function passport_key($txt, $encrypt_key) {
- // 将 $encrypt_key 赋为 $encrypt_key 经 md5() 后的值
- $encrypt_key = md5($encrypt_key);
- // 变量初始化
- $ctr = 0;
- $tmp = '';
- // for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
- for($i = 0; $i < strlen($txt); $i++) {
- // 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
- $ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
- // $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
- // 与 $encrypt_key 的第 $ctr + 1 位取异或。然后 $ctr = $ctr + 1
- $tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
- }
- // 返回 $tmp 的值作为结果
- return $tmp;
- }
- /**
- * Passport 信息(数组)编码函数
- *
- * @param array 待编码的数组
- *
- * @return string 数组经编码后的字串
- */
- function passport_encode($array) {
- // 数组变量初始化
- $arrayenc = array();
- // 遍历数组 $array,其中 $key 为当前元素的下标,$val 为其对应的值
- foreach($array as $key => $val) {
- // $arrayenc 数组增加一个元素,其内容为 "$key=经过 urlencode() 后的 $val 值"
- $arrayenc[] = $key.'='.urlencode($val);
- }
- // 返回以 "&" 连接的 $arrayenc 的值(implode),例如 $arrayenc = array('aa', 'bb', 'cc', 'dd'),
- // 则 implode('&', $arrayenc) 后的结果为 ”aa&bb&cc&dd"
- return implode('&', $arrayenc);
}
?>
注释都在里面的,可以稍微修改下变成自己需要的
dz后台通行证的设置是这样的:
应用程序 URL 地址:http://localhost/www/discuz/
通行证私有密匙:ffffffffffff
验证字串有效期(秒):3600
应用程序注册地址:register.php //注册模块未写,原理差不多
应用程序登录地址:login.php?action=login
应用程序退出地址:login.php?action=logout
login.php是放在discuz下面的,dz的程序是放在discuz下面的upload目录,基本结构就是这样