mirror of
https://github.com/DzzXH/DzzOffice.git
synced 2026-01-15 14:35:21 +08:00
更新至V1.82,更新内容在笔记中查看
This commit is contained in:
@@ -53,7 +53,7 @@
|
||||
<input type="text" class="form-control" id="email_$loginhash" placeholder="{lang email_username}" name="email" autocomplete="off">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" id="password3_$loginhash" placeholder="{lang user_login_password}" name="password" onfocus="this.type='password'" autocomplete="off">
|
||||
<input type="password" class="form-control" id="password3_$loginhash" placeholder="{lang user_login_password}" name="password" onfocus="this.type='password'" autocomplete="off">
|
||||
</div>
|
||||
<!--{/if}-->
|
||||
<!--{if $seccodecheck}-->
|
||||
|
||||
@@ -36,7 +36,7 @@ html {
|
||||
<input type="text" id="email_$loginhash" name="email" autocomplete="off" placeholder="{lang email_username}"/>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<input type="text" id="password3_$loginhash" name="password" onfocus="this.type='password'" autocomplete="off" placeholder="{lang user_login_password}"/>
|
||||
<input type="password" id="password3_$loginhash" name="password" onfocus="this.type='password'" autocomplete="off" placeholder="{lang user_login_password}"/>
|
||||
</div>
|
||||
<!--{/if}-->
|
||||
<!--{if $seccodecheck}-->
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
<input class="w-full text-base px-4 py-2 border-b border-gray-300 focus:outline-none rounded-2xl focus:border-indigo-500" type="text" id="email_$loginhash" name="email" autocomplete="off" placeholder="{lang email_username}"/>
|
||||
</div>
|
||||
<div class="mt-8 content-center">
|
||||
<input class=" w-full content-center text-base px-4 py-2 border-b rounded-2xl border-gray-300 focus:outline-none focus:border-indigo-500" type="text" id="password3_$loginhash" name="password" onfocus="this.type='password'" autocomplete="off" placeholder="{lang user_login_password}"/>
|
||||
<input class=" w-full content-center text-base px-4 py-2 border-b rounded-2xl border-gray-300 focus:outline-none focus:border-indigo-500" type="password" id="password3_$loginhash" name="password" onfocus="this.type='password'" autocomplete="off" placeholder="{lang user_login_password}"/>
|
||||
</div>
|
||||
<!--{/if}-->
|
||||
<!--{if $seccodecheck}-->
|
||||
|
||||
273
user/sso/classes/oauth.php
Normal file
273
user/sso/classes/oauth.php
Normal file
@@ -0,0 +1,273 @@
|
||||
<?php
|
||||
namespace user\sso\classes;
|
||||
|
||||
use \core as C;
|
||||
class Oauth{
|
||||
|
||||
private $secretid = '';//秘钥
|
||||
|
||||
private $keyid = '';//验证key
|
||||
|
||||
private $token = '';//验证token
|
||||
|
||||
public $expire = 2592000;//token过期时间
|
||||
|
||||
public $backurl = '';//回调地址
|
||||
|
||||
public $usename = '';//应用名称
|
||||
|
||||
public $host = '';//绑定域名
|
||||
|
||||
public $refreshexpire = 31536000;//刷新令牌过期时间
|
||||
|
||||
public $state = '';
|
||||
|
||||
|
||||
public function setkeyserectid($backurl,$usename = ''){//设置key和秘钥
|
||||
|
||||
$this->keyid = random(10);//生成验证key
|
||||
|
||||
$this->secretid = random(30);//生成秘钥
|
||||
|
||||
$this->backurl = $backurl;//回调地址
|
||||
|
||||
$this->usename = $usename;//应用名称
|
||||
|
||||
$backarr = parse_url($backurl);
|
||||
|
||||
$host = $backarr['host'];
|
||||
if(empty($host)){
|
||||
return self::showError(4006);
|
||||
|
||||
}
|
||||
if(C::t('user_sdk')->fetch_by_host($host)){//查询域名对应sdk
|
||||
|
||||
$setarr = array('key'=>$this->keyid,'secret'=>$this->secretid,'backurl'=>$this->backurl,'usename'=>$this->usename);
|
||||
|
||||
if(C::t('user_sdk')->update_by_host($host,$setarr)){//更新sdk
|
||||
|
||||
return array('keyid'=>$this->keyid,'secretid'=>$this->secretid);
|
||||
|
||||
}else{
|
||||
return self::showError(4003);
|
||||
}
|
||||
|
||||
}else{//生成sdk
|
||||
|
||||
$setarr = array('key'=>$this->keyid,'secret'=>$this->secretid,'host'=>$host,'backurl'=>$this->backurl,'usename'=>$this->useid);
|
||||
|
||||
if(C::t('user_sdk')->insert($setarr)){
|
||||
|
||||
return array('keyid'=>$this->keyid,'secretid'=>$this->secretid);
|
||||
|
||||
}else{
|
||||
|
||||
return self::showError(4003);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getrefererhost(){//获取之前页域名
|
||||
|
||||
$url = $_SERVER["HTTP_REFERER"];
|
||||
|
||||
$parseurl = parse_url($url);
|
||||
|
||||
$host = $parseurl['host'];
|
||||
|
||||
return $host;
|
||||
}
|
||||
|
||||
public function gettoken($keyid){//获取token
|
||||
|
||||
$this->keyid = $keyid;//key
|
||||
|
||||
if($return = C::t('user_sdk')->fetch($this->keyid)){//检查对应sdk
|
||||
|
||||
$this->secretid = $return['secret'];//获取对应秘钥
|
||||
|
||||
$this->createToken();//生成token
|
||||
|
||||
$refreshtoken = $this->createRefreshStr($this->secretid);////生成刷新令牌
|
||||
|
||||
$setarr = array('tokenid'=>$this->token,'date'=>time(),'expire'=>$this->expire,'refreshtoken'=>$refreshtoken);
|
||||
|
||||
if(C::t('user_salf')->update($this->uid,$setarr)){//存储安全信息
|
||||
|
||||
|
||||
return array('tokenid'=>$this->token,'date'=>$setarr['date'],'expire'=>$this->expire,'refreshtoken'=>$refreshtoken);
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
return self::showError(4001);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function chk_callback_host($keyid,$backurl = ''){//检查回调地址域名是否合法
|
||||
|
||||
if($return = C::t('user_sdk')->fetch($keyid)){
|
||||
|
||||
$this->host = $return['host'];
|
||||
|
||||
$backarr = parse_url($backurl);
|
||||
|
||||
$host = $backarr['host'];
|
||||
|
||||
if($host != $this->host){
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(strpos($return['backurl'],',') !== false){
|
||||
|
||||
$backurls = explode(',',$return['backurl']);
|
||||
|
||||
}else{
|
||||
|
||||
$backurls[] = $return['backurl'];
|
||||
|
||||
}
|
||||
|
||||
if($backurl && in_array($backurl,$backurls)){
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function createRefreshStr($secretid){//生成刷新令牌
|
||||
|
||||
return dzzencode($this->uid.$secretid.random(6),random(3));
|
||||
}
|
||||
|
||||
public function refreshtoken($token,$refreshtokenid){//刷新token
|
||||
|
||||
if($return = C::t('user_salf')->fetch_by_tokenid($token)){//获取对应安全信息
|
||||
|
||||
if($return['refreshtoken'] == $refreshtokenid && (time()-$return['date']) < $this->refreshexpire){//验证刷新令牌,判断刷新令牌是否过期
|
||||
|
||||
$sdkinfo = C::t('user_sdk')->fetch($return['keyid']);
|
||||
|
||||
$this->secretid = $sdkinfo['secret'];
|
||||
|
||||
$this->keyid = $sdkinfo['key'];
|
||||
|
||||
$this->uid = $sdkinfo['uid'];
|
||||
|
||||
$this->createToken();//生成token
|
||||
|
||||
$refreshtoken = $this->createRefreshStr();//生成刷新令牌
|
||||
|
||||
$setarr = array('tokenid'=>$this->token,'date'=>time(),'refreshtoken'=>$refreshtoken);
|
||||
|
||||
if(C::t('user_salf')->update($this->keyid,$setarr)){//更新token
|
||||
|
||||
return array('tokenid'=>$this->token,'date'=>time(),'refreshtoken'=>$refreshtoken,'expire'=>$return['expire']);
|
||||
}
|
||||
}else{
|
||||
|
||||
return $this->showError(4005);
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
return $this->showError(4001);
|
||||
}
|
||||
}
|
||||
|
||||
public function chk_token($token){//检查token是否可用
|
||||
|
||||
if(empty($token))self::showError(4004);
|
||||
|
||||
if($return = C::t('user_salf')->fetch_by_tokenid($token)){//获取token安全信息
|
||||
|
||||
return ((time() - $return['date']) < $return['expire']) ? $return['uid']:false;//验证token
|
||||
|
||||
}else{
|
||||
|
||||
return self::showError(4004);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function createToken(){//创建token
|
||||
|
||||
$this->token = md5($this->uid.$this->secretid.$this->keyid.time());//生成token
|
||||
|
||||
}
|
||||
|
||||
public function showError($code,$desc = '$'){//错误输出
|
||||
|
||||
if($desc == '$'){
|
||||
|
||||
switch($code){
|
||||
case 4001: $msg = 'Key Not Validated';
|
||||
break;
|
||||
case 4002: $msg = 'Domain Is Illegal';
|
||||
break;
|
||||
case 4003: $msg = 'System Busy';
|
||||
break;
|
||||
case 4004: $msg = 'Token Unavailable Or Expired';
|
||||
break;
|
||||
case 4005: $msg = 'Refreshtoken Unavailable Or Expired';
|
||||
break;
|
||||
case 4006: $msg = 'Domain Name Or Callback Address Is Illegal';
|
||||
break;
|
||||
case 4007: $msg = 'Request Validation Not Passed';
|
||||
break;
|
||||
default: $msg = "System Mistake";
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
$msg = $desc;
|
||||
|
||||
}
|
||||
|
||||
return array('code'=>$code,'msg'=>$msg);
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
public function safecode(){//code加密
|
||||
|
||||
$code = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($this->secretid), $this->code, MCRYPT_MODE_CBC, md5(md5($this->secretid))));
|
||||
|
||||
$code = base64_encode($code);
|
||||
|
||||
$code = str_replace(array('+','/','='),array('-','_',''),$code);
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
public function dsafecode($code){//解密code
|
||||
|
||||
$code = str_replace(array('-','_'),array('+','/'),$code);
|
||||
|
||||
$mod4 = strlen($code) % 4;
|
||||
|
||||
if ($mod4) {
|
||||
|
||||
$code .= substr('====', $mod4);
|
||||
|
||||
}
|
||||
$code = base64_decode($code);
|
||||
|
||||
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($this->secretid), base64_decode($code), MCRYPT_MODE_CBC, md5(md5($this->secretid))), "\0");
|
||||
}
|
||||
|
||||
public function dsafesecret($keyid,$safesecret){
|
||||
|
||||
return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($this->keyid), base64_decode($safesecret), MCRYPT_MODE_CBC, md5(md5($this->keyid)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
124
user/sso/index.php
Normal file
124
user/sso/index.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
if (!defined('IN_DZZ')) {
|
||||
|
||||
exit('Access Denied');
|
||||
}
|
||||
global $_G;
|
||||
|
||||
$oauth = new user\sso\classes\Oauth();
|
||||
|
||||
$do = isset($_GET['do']) ? $_GET['do']:'';
|
||||
|
||||
if($do == 'getkeyid'){//申请验证keyid和秘钥
|
||||
|
||||
$backurl = isset($_GET['backurl']) ? $_GET['backurl']:'';
|
||||
|
||||
$result = $oauth->setkeyserectid($backurl);
|
||||
|
||||
exit(json_encode($result));
|
||||
|
||||
}elseif($do == 'getcode'){//获取验证字符串
|
||||
|
||||
$keyid = isset($_GET['appid']) ? $_GET['appid']:'';
|
||||
|
||||
$backurl = isset($_GET['client_uri']) ? $_GET['client_uri']:'';
|
||||
|
||||
$state = isset($_GET['state']) ? $_GET['state']:'';
|
||||
|
||||
if(!$oauth->chk_callback_host($keyid,$backurl)) {
|
||||
|
||||
exit(json_encode($oauth->showError(4006)));
|
||||
}
|
||||
|
||||
if($_G['uid']){
|
||||
|
||||
$uid = intval($_G['uid']);
|
||||
|
||||
$oauth->code = $uid;
|
||||
|
||||
$safecode = $oauth->safecode();
|
||||
|
||||
if(!$r = C::t('user_salf')->fetch($uid)) {
|
||||
|
||||
C::t('user_salf')->insert(array('keyid' => $keyid, 'uid' => $uid));
|
||||
}
|
||||
|
||||
$j = (strpos($backurl,'?') == false) ? '?':'&';
|
||||
|
||||
$backurl = $backurl.$j.'safecode='.$safecode.'&state='.$state;
|
||||
|
||||
header("location:$backurl");
|
||||
|
||||
exit();
|
||||
|
||||
}else{
|
||||
|
||||
$referer = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'];
|
||||
|
||||
$loginurl = $_G['siteurl']."user.php?mod=login&op=logging&action=login&referer=".urlencode($referer);
|
||||
|
||||
header('location:'.$loginurl);
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
}elseif($do == 'gettoken'){//获取token
|
||||
|
||||
$keyid = isset($_GET['appid']) ? $_GET['appid']:'';
|
||||
|
||||
$code = isset($_GET['safecode']) ? $_GET['safecode']:'';
|
||||
|
||||
$uid = $oauth->dsafecode($code);
|
||||
|
||||
if($return = C::t('user_salf')->fetch($uid)){
|
||||
|
||||
if($return['keyid'] != $keyid){
|
||||
|
||||
exit(json_encode($oauth->showError(4001)));
|
||||
}
|
||||
$oauth->uid = $uid;
|
||||
|
||||
}else{
|
||||
|
||||
exit(json_encode($oauth->showError(4007)));
|
||||
}
|
||||
|
||||
$result = $oauth->gettoken($keyid);
|
||||
|
||||
exit(json_encode($result));
|
||||
|
||||
}elseif($do == 'updatetoken'){//刷新token
|
||||
|
||||
$refreshtoken = isset($_GET['refreshtoken']) ? $_GET['refreshtoken']:'';
|
||||
|
||||
$tokenid = isset($_GET['tokenid']) ? $_GET['tokenid']:'';
|
||||
|
||||
$result = $oauth->refreshtoken($tokenid,$refreshtoken);
|
||||
|
||||
exit(json_encode($result));
|
||||
|
||||
|
||||
|
||||
}elseif($do == 'getuserbasic'){//获取用户信息
|
||||
|
||||
$tokenid = isset($_GET['tokenid']) ? $_GET['tokenid']:'';
|
||||
|
||||
if(!$uid = $oauth->chk_token($tokenid)) exit(json_encode($oauth->showError(4004)));
|
||||
|
||||
$info = C::t('user')->fetch_userbasic_by_uid($uid);
|
||||
|
||||
exit(json_encode($info));
|
||||
|
||||
}elseif($do == 'getuseratavar'){
|
||||
|
||||
$tokenid = isset($_GET['tokenid']) ? $_GET['tokenid']:'';
|
||||
|
||||
if(!$uid = $oauth->chk_token($tokenid)) exit(json_encode($oauth->showError(4004)));
|
||||
|
||||
$openid = $oauth->safecode($uid);
|
||||
|
||||
exit(json_encode(array('atavar_url'=>$_G['siteurl']."user.php?mod=sso&op=avatar&openid=".$openid)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
67
user/sso/login.php
Normal file
67
user/sso/login.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
$do = $_GET['do'];
|
||||
if($_G['setting']['quick_login']){
|
||||
$time=trim($_GET['time']);
|
||||
$username = trim($_GET['username']);
|
||||
$email= trim($_GET['email']);
|
||||
$token= trim($_GET['token']);
|
||||
if($email && $username && $token && $time){
|
||||
if ($time < (time() - 60)) showmessage('验证时间已过期,请重新获取',$_G['siteurl']);
|
||||
$key=$_G['setting']['quick_key'];
|
||||
$md5=md5(''.$username.''.''.$email.''.''.$key.''.''.$time.'');
|
||||
if (!($token === $md5)) {
|
||||
showmessage('token不正确',$_G['siteurl']);
|
||||
return;
|
||||
}
|
||||
if(($user=C::t('user')->fetch_by_username($username)) || ($user=C::t('user')->fetch_by_email($email))){//用户已经存在时
|
||||
if ($user['adminid']) showmessage('为了安全,禁止管理员通过这种方式登录',$_G['siteurl']);
|
||||
$idstring = explode('_', $user['emailsenddate']);
|
||||
if ($idstring[0] == (time() - $idstring[1]) < 86400) {
|
||||
dsetcookie('auth', authcode("{$user['password']}\t{$user['uid']}", 'ENCODE'), 0, 1, true);
|
||||
}
|
||||
showmessage('Login_success',$_G['siteurl']);
|
||||
}else{
|
||||
if($_G['setting']['bbclosed']) showmessage(lang('site_closed_please_admin'));//判断站点是否关闭
|
||||
require_once libfile('function/user','','user');
|
||||
if(!check_username($username)) exit(json_encode(array('error'=>lang('user_name_sensitive'))));
|
||||
$password=$_G['setting']['quick_password'];
|
||||
$user=uc_add_user($username, $password, $email);
|
||||
$uid=$user['uid'];
|
||||
if($uid<1) exit(json_encode(array('error'=>lang('import_failure'))));
|
||||
$base = array(
|
||||
'uid' => $uid,
|
||||
'adminid' => 0,
|
||||
'groupid' =>9,
|
||||
'regdate' => TIMESTAMP,
|
||||
'emailstatus' => 1,
|
||||
);
|
||||
if($_GET['mobile']){
|
||||
if(!preg_match("/^\d+$/",$_GET['mobile'])){
|
||||
}elseif(C::t('user')->fetch_by_phone($_GET['mobile']) ) {
|
||||
}else{
|
||||
$base['phone']=$_GET['mobile'];
|
||||
}
|
||||
}
|
||||
if($_GET['weixinid']){
|
||||
if(!preg_match("/^[a-zA-Z\d_]{5,}$/i",$_GET['weixinid'])){
|
||||
}elseif(C::t('user')->fetch_by_weixinid($_GET['weixinid'])) {
|
||||
}else{
|
||||
$base['weixinid']=$_GET['weixinid'];
|
||||
}
|
||||
}
|
||||
$sitename=$_G['setting']['sitename'];
|
||||
C::t('user')->update($uid,$base);
|
||||
|
||||
$idstring = explode('_', $user['emailsenddate']);
|
||||
|
||||
if ($idstring[0] == (time() - $idstring[1]) < 86400) {
|
||||
|
||||
dsetcookie('auth', authcode("{$user['password']}\t{$user['uid']}", 'ENCODE'), 0, 1, true);
|
||||
|
||||
}
|
||||
showmessage('Login_success',$_G['siteurl']);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
showmessage('未开启快速登录',$_G['siteurl']);
|
||||
}
|
||||
Reference in New Issue
Block a user