Files
youlegames/codes/agent/game-docker/api/source/apis/login.php
2026-04-10 16:44:13 +08:00

1848 lines
62 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, PATCH, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Authorization, Content-Length, X-Requested-With");
header("Access-Control-Allow-Credentials: true");
// 加载环境变量
require_once dirname(dirname(dirname(__DIR__))) . '/env_config.php';
header("Content-Type: text/html; charset=utf-8");
/**
* 登录相关接口
*/
use phprs\util\Verify;
use phprs\util\exceptions\Forbidden;
use phprs\util\Logger;
use phprs\util\exceptions\NotFound;
use phprs\ezsql\Sql;
use phprs\util\exceptions\BadRequest;
define('LOGINPARAMETER_CALLBACK', 'login_callback');
class LoginCallbackInformation
{
public $sid;
public $scode;
public $app_id;
public $dev_key;
public $market_key;
public $return_url;
public $return_parameter;
public $fail_url;
public function __construct(
$sid = '',
$scode = '',
$app_id = '',
$dev_key = '',
$market_key = '',
$return_url = '',
$return_parameter = '',
$fail_url = '')
{
$this->sid = $sid;
$this->scode = $scode;
$this->app_id = $app_id;
$this->dev_key = $dev_key;
$this->market_key = $market_key;
$this->return_url = $return_url;
$this->return_parameter = $return_parameter;
$this->fail_url = $fail_url;
}
public function to_array()
{
return (array)$this;
}
public function to_string()
{
return json_encode($this, JSON_UNESCAPED_UNICODE);
}
public function from_array($array)
{
foreach ($array as $key => $value)
{
if (property_exists($this, $key))
$this->$key = $value;
}
return true;
}
public function from_string($string)
{
return $this->from_array((array)json_decode($string));
}
/**
* @param $string
* @return LoginCallbackInformation
*/
static public function CreateWithString($string)
{
$return = new LoginCallbackInformation();
$return->from_string($string);
return $return;
}
/**
* @param $array
* @return LoginCallbackInformation
*/
static public function CreateWithArray($array)
{
$return = new LoginCallbackInformation();
$return->from_array($array);
return $return;
}
}
/**
*
* 登录管理
* @path("/login")
*/
class Login extends apiBase
{
/**
* 获得登录方式
* @route({"GET","/"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return("body")
*/
public function getLoginType()
{
$result = array(
//0 => array(
// 'name' => '微信登录',
// 'url' => $this->getFullUrl('/api/login/weixin'),
// 'third' => 'weixin',
//),
//1 => array(
// 'name' => 'QQ登录',
// 'url' => $this->getFullUrl('/api/login/qq'),
// 'third' => 'qq',
//),
0 => array(
'name' => '聚开心登录',
'url' => $this->getFullUrl('/api/login/jkx'),
'third' => 'jkx',
),
);
return $result;
}
/**
* 获得登录方式
* @route({"GET","/querylist"})
* @route({"POST","/querylist"})
* @param({"market_key","$._POST.market_key"}) 门店key
* @param({"logintype","$._POST.logintype"}) 登陆方式
* @param({"silence","$._POST.silence"}) 是否静默方式
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
* @return("body")
*/
public function getLoginList($market_key = '', $logintype = 0, $silence = null)
{
// 尝试使用框架注入的数据库连接,如果失败则使用直接连接
$db = $this->db;
if (!$db) {
try {
$db = new PDO(
"mysql:host=" . env('API_DB_HOST', 'rm-bp1btyuwq77591x0jpo.mysql.rds.aliyuncs.com') . ":" . env('API_DB_PORT', '3306') . ";dbname=" . env('API_DB_NAME', 'youlehudong') . ";charset=utf8",
env('API_DB_USER', 'games'),
env('API_DB_PASSWORD', 'Games0791!!'),
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
} catch (Exception $e) {
// 如果数据库连接失败,返回默认的微信登录配置
$default_data = [[
'type_id' => 2,
'type_key' => '0002',
'type_name' => '微信登录',
'image' => 'img/wx.png',
'url' => $this->getFullUrl('api/login/weixin'),
'component' => null,
'is_third' => 1,
'third_flag' => 'weixin'
]];
return json_encode($default_data, JSON_UNESCAPED_UNICODE);
}
}
if (empty($market_key))
{
$condition = 'is_enabled = 1 and is_silence = ' . intval(empty($silence) ? 0 : $silence);
if (!empty($logintype))
$condition .= sprintf(' and type_id = %d', intval($logintype));
$data = Sql::Select('type_id,type_key,type_name,image,url,component,is_third,third_flag')
->from('syweb_logintype_base')
->where($condition)
->get($db);
}
else
{
$condition = 'a.type_key = b.type_key and a.is_enabled = 1 and b.is_enabled = 1 and market_key = ? and a.is_silence = ' . intval(empty($silence) ? 0 : $silence);
if (!empty($logintype))
$condition .= sprintf(' and a.type_id = %d', intval($logintype));
$data = Sql::Select('a.type_id,a.type_key,a.type_name,a.image,a.url,a.component,a.is_third,a.third_flag')
->from('syweb_logintype_base a, syweb_logintype_market b')
->where($condition, $market_key)
->get($db);
}
foreach ($data as $key=>&$value)
{
$value['url'] = $this->getFullUrl($value['url']);
}
return json_encode($data, JSON_UNESCAPED_UNICODE);
}
/**
* 使用QQ授权登录
* @route({"GET","/qq"})
* @param({"appid","$._GET.appid"}) 应用appid
* @param({"devkey","$._GET.devkey"}) 开发者key
* @param({"market_key","$._GET.market_key"}) 门店key
* @param({"scode","$._GET.scode"}) 客户端生成的Scode
* @param({"target","$._GET.target"}) 客户端需要回调的地址
* @param({"state","$._POST.state"}) 随机参数
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function qqLogin($appid = "", $devkey = "", $market_key = "", $scode, $target, $state = '')
{
require_once __DIR__ . '/../../loginLib/qq/API/qqConnectAPI.php';
if (empty($appid))
{
$result["error"] = '1';
$result["error_code"] = 10001; // 未传入appid参数
return $result;
}
if (empty($devkey))
{
$result["error"] = '1';
$result["error_code"] = 10002; // 未传入devkey参数
return $result;
}
$devList = Sql::select('syweb_admin.*')
->from('syweb_admin')
->where('syweb_admin.type=2 and syweb_admin.devkey=? and syweb_admin.status=1', $devkey)
->get($this->db, null);
if (empty($devList) || count($devList) <= 0)
{
$result["error"] = '1';
$result["error_code"] = 10003; // devkey无效
return $result;
}
$devInfo = $devList[0];
$appList = Sql::select('syweb_app.*')
->from('syweb_app')
->where('syweb_app.appid=? and syweb_app.dev_id=? and status=1', $appid, $devInfo['id'])
->get($this->db, null);
if (empty($appList) || count($appList) <= 0)
{
$result["error"] = '1';
$result["error_code"] = 10004; // 指定的应用不存在或未被审核
return $result;
}
$appInfo = $appList[0];
$marketList = Sql::select('syweb_market.*')
->from('syweb_market')
->where('syweb_market.marketid=?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
{
$result["error"] = '1';
$result["error_code"] = 10007; // 指定的商家不存在
return $result;
}
$marketInfo = $marketList[0];
//开启一个会话
session_start();
$_SESSION[LOGINPARAMETER_CALLBACK] = (new LoginCallbackInformation('', $scode, $appInfo['id'], $devkey, $marketInfo['id'], $target))->to_string();
$qc = new QC();
$qc->qq_login();
}
/**
* QQ授权登录回调
* @route({"GET","/qq/callback"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function qqLoginCallback()
{
session_start();
$scode = "";
$target = "";
$app_id = "";
$devkey = "";
$market_id = "";
if (isset($_SESSION[LOGINPARAMETER_CALLBACK]))
{
$login = LoginCallbackInformation::CreateWithString($_SESSION[LOGINPARAMETER_CALLBACK]);
$scode = $login->scode;
$target = $login->return_url;
$app_id = $login->app_id;
$devkey = $login->dev_key;
$market_id = $login->market_key;
}
if (!$scode || !$target || !$app_id || !$devkey || !$market_id)
{
return "登录失败!";
}
require_once __DIR__ . '/../../loginLib/qq/API/qqConnectAPI.php';
$qc = new QC();
$access_token = $qc->qq_callback();
$openId = $qc->get_openid();
if (empty($openId))
{
return "授权登录失败!";
}
// 获得QQ授权获得的QQ信息
$qc = new QC($access_token, $openId);
$userinfo = $qc->get_user_info();
/*
foreach($userinfo as $k => $v){
echo $k.'=='.$v.'<br>';
}
$ret = $qc->get_info();
if($ret['ret'] == 0){
foreach($ret['data'] as $k => $v){
echo $k.'=='.$v.'<br>';
}
}else{
echo "<meta charset='utf-8' />";
echo "获取失败,请开启调试查看原因";
}
exit;*/
// 根据QQ对应的openId查询数据库对应的全局用户信息
$fan = getUserByOpenId($market_id, $openId, AUTHTYPE_QQ, $this->db);
$sid = "";
$pdo = $this->db;
$pdo->beginTransaction();
if (!empty($fan))
{
// 查询粉丝对应的会员详细信息
$members = getQqUserByUId($fan['id'], $this->db);
if (empty($member))
{
if ($userinfo['ret'] == 0)
{// 假如授权返回错误消息,则重新登录
header('Location: ' . $target);
}
}
$member['uid'] = $fan['id'];
$member['openid'] = $fan['openid'];
// 粉丝昵称
$member['nickname'] = stripcslashes($userinfo['nickname']);
$member['province'] = $userinfo['province'];//所属省份
$member['city'] = $userinfo['city'];//所属省份
$member['year'] = $userinfo['year'];//所属城市
$member['gender'] = $userinfo['gender'];// 性别
$member['figureurl_qq_1'] = $userinfo['figureurl_qq_1'];// QQ小头像
$member['figureurl_qq_2'] = $userinfo['figureurl_qq_2'];// QQ大头像
$member['figureurl'] = $userinfo['figureurl'];// 大头像
$member['figureurl_1'] = $userinfo['figureurl_1'];// 中头像
$member['figureurl_2'] = $userinfo['figureurl_2'];// 小头像
$member['vip'] = $userinfo['vip'];
$member['level'] = $userinfo['level'];
$member['yellow_vip_level'] = $userinfo['yellow_vip_level'];
$member['is_yellow_year_vip'] = $userinfo['is_yellow_year_vip'];
// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode, AUTHTYPE_QQ, $fan['openid'], '', $market_id, $this->db, $pdo);
updateQqUserInfo($member, $this->db, $pdo);
}
else
{// 假如数据库中还不存在对应的粉丝信息记录
if ($userinfo['ret'] == 0)
{// 假如授权返回错误消息,则重新登录
header('Location: ' . $target);
}
// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode, AUTHTYPE_QQ, $openId, '', $market_id, $this->db, $pdo);
$userinfo['uid'] = $globalUserInfoId;// 全局用户ID
$userinfo['openid'] = $openId;
updateQqUserInfo($userinfo, $this->db, $pdo);
}
$pdo->commit();
// 新创建的全局用户信息从中获取新创建的sid
$globalUserInfo = getUserById($globalUserInfoId, $this->db);
$sid = $globalUserInfo["sid"];
if (strstr($target, '?'))
{
if (strstr($target, '&'))
{
$target .= '&sid=' . $sid;
}
else
{
$target .= 'sid=' . $sid;
}
}
else
{
$target .= '?sid=' . $sid;
}
// 登录成功后跳转到客户端传入的回调页面
header('Location: ' . $target);
}
/**
* 使用微信授权登录
* @route({"GET","/weixin"})
* @param({"appid","$._GET.appid"}) 应用appid
* @param({"devkey","$._GET.devkey"}) 开发者key
* @param({"market_key","$._GET.market_key"}) 门店key
* @param({"scode","$._GET.scode"}) 客户端生成的Scode
* @param({"target","$._GET.target"}) 客户端需要回调的地址
* @param({"fail_target","$._GET.fail_target"}) 发生错误时,客户端回调的页面
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function weixinLogin($appid = "", $devkey = "", $market_key = "", $scode = "", $target = "", $fail_target = "")
{
if (empty($appid))
$this->forwardUrl($fail_target, new returnObject(1, 10001, '未传入appid参数!'));
if (empty($devkey))
$this->forwardUrl($fail_target, new returnObject(1, 10002, '未传入devkey参数!'));
$devList = Sql::select('a.*')
->from('syweb_admin a')
->where('a.type=2 and a.admin_key=? and a.status=1', $devkey)
->get($this->db, null);
if (empty($devList) || count($devList) <= 0)
$this->forwardUrl($fail_target, new returnObject(1, 10003, 'devkey无效或未经过审核!'));
$devInfo = $devList[0];
/*
$appBaseList = Sql::select('a.*')
->from('syweb_app_base a')
->where('a.ref_key=? and a.dev_key=? and a.status=10', $appid, $devInfo['admin_key'])
->get($this->db, null);
if (empty($appBaseList) || count($appBaseList) <= 0)
{
$this->forwardUrl($fail_target, new returnObject(1, 10004, '指定的应用不存在或未被审核!'));
}
$appBaseKey = $appBaseList[0]["app_key"];
$appList = Sql::select('a.*')
->from('syweb_app a')
->where('a.ref_key=? and a.dev_key=? and a.status=10', $appBaseKey, $devInfo['admin_key'])
->get($this->db, null);
if (empty($appList) || count($appList) <= 0)
{
$this->forwardUrl($fail_target, new returnObject(1, 10005, '指定的应用不存在或未被审核!'));
}
$appInfo = $appList[0];
$marketList = Sql::select('a.*')
->from('syweb_market a')
->where('a.market_key=?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
{
$this->forwardUrl($fail_target, new returnObject(1, 10007, '指定的门店不存在或已经被删除!'));
}
$marketInfo = $marketList[0];
*/
$appList = Sql::select('b.*')
->from('syweb_app_base a, syweb_app b')
->where('a.app_key = b.ref_key and a.status = b.status and a.dev_key = b.dev_key and a.ref_key = ? and a.dev_key = ? and a.status = 10', $appid, $devInfo['admin_key'])
->get($this->db, null);
if (empty($appList) || count($appList) <= 0)
$this->forwardUrl($fail_target, new returnObject(1, 10005, '指定的应用不存在或未被审核!'));
$appInfo = $appList[0];
$marketList = Sql::select('a.*')
->from('syweb_market a, syweb_logintype_market b')
->where('a.market_key = b.market_key and b.type_key = \'0002\' and b.is_enabled != 0 and a.market_key = ?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
$this->forwardUrl($fail_target, new returnObject(1, 10007, '指定的门店不存在或已经被删除, 或该门店不支持该登录方式!'));
$marketInfo = $marketList[0];
$account = array();
$account["key"] = $marketInfo['weixin_appid'];
$weixin = new WeiXinAccount($account);
/*
// 分析主域名中的参数 begin
$referUrls = parse_url($_SERVER['HTTP_REFERER']); /// 请求方的参数
$callback_paramers = "";
if (!empty($referUrls['query']))
{
// 假如传入了参数
$callback_paramers_list = explode("&", $referUrls['query']);
if (!empty($callback_paramers_list) && count($callback_paramers_list) > 0)
{
foreach ($callback_paramers_list as $key => $value)
{
if (!strstr($value, 'appid=') &&
!strstr($value, 'devkey=') &&
!strstr($value, 'market_key=') &&
!strstr($value, 'scode=') &&
!strstr($value, 'target=') &&
!strstr($value, 'state=')
)
{
if (empty($callback_paramers))
{
$callback_paramers = $value;
}
else
{
$callback_paramers .= '&' . $value;
}
}
}
}
}
$newTarget = '';
$targetUrls = parse_url($target);
if (!empty($targetUrls))
{
$newTarget = $targetUrls['scheme'] . '://' . $targetUrls['host'] . ((!empty($targetUrls['port']) && $targetUrls['port'] != '80') ? ':' . $targetUrls['port'] : '') . $targetUrls['path'];
}
if (!empty($callback_paramers))
{
if (strstr($newTarget, '?'))
{
if (strstr($newTarget, '&'))
{
$newTarget .= '&' . $callback_paramers;
}
else
{
$newTarget .= $callback_paramers;
}
}
else
{
$newTarget .= '?' . $callback_paramers;
}
}
// 分析主域名中的参数
*/
/// 剔除必须的参数.
$needed = array('sid', 'scode', 'appid', 'devkey', 'market_key', 'target', 'fail_target');
/// 获取请求参数
$refer_paramers = GetAttachParameters($needed);
$parameters = '';
foreach ($refer_paramers as $k => $v)
{
$parameters .= "&{$k}={$v}";
}
// 开启一个会话
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
$callbackInfo = new LoginCallbackInformation('', $scode, $appInfo['id'], $devkey, $marketInfo["market_key"], $target, $parameters, $fail_target);
$_SESSION[LOGINPARAMETER_CALLBACK] = $callbackInfo->to_string();
// 记录session存储的调试信息
error_log("WeChat Login - Storing session parameters:");
error_log("Session ID: " . session_id());
error_log("Session callback info: " . $_SESSION[LOGINPARAMETER_CALLBACK]);
error_log("Parameters stored - scode: $scode, app_id: " . $appInfo['id'] . ", devkey: $devkey, market_key: " . $marketInfo["market_key"]);
///$callback = "http://" . $this::$domain . "/api/login/weixin/callback";
$callback = $this->getFullUrl('/api/login/weixin/callback');
$state = 'ylsid-' . session_name();
$forward = $weixin->getOauthUserInfoUrl($callback, $state);
//exit($forward);
header('Location: ' . $forward);
exit();
}
/**
* 微信授权登录回调(10010-10030)
* @route({"GET","/weixin/callback"})
* @param({"code", "$._GET.code"})
* @param({"state", "$._GET.state"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function weixinLoginCallback($code = '', $state = '')
{
// 在任何输出之前启动session
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
// 添加错误处理和调试
error_reporting(E_ALL);
ini_set('display_errors', 1);
try {
// 记录调试信息
error_log("WeChat Login Callback - Code: $code, State: $state");
error_log("Session ID: " . session_id());
error_log("Session data: " . print_r($_SESSION, true));
// 检查数据库连接
if (!$this->db) {
try {
$this->db = new PDO(
"mysql:host=" . env('API_DB_HOST', 'rm-bp1btyuwq77591x0jpo.mysql.rds.aliyuncs.com') . ":" . env('API_DB_PORT', '3306') . ";dbname=" . env('API_DB_NAME', 'youlehudong') . ";charset=utf8",
env('API_DB_USER', 'games'),
env('API_DB_PASSWORD', 'Games0791!!'),
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
} catch (Exception $e) {
error_log("Database connection failed: " . $e->getMessage());
echo '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>登录失败</title></head><body>';
echo '<h1>数据库连接失败</h1><p>请稍后重试</p>';
echo '</body></html>';
return;
}
}
$scode = '';
$app_id = '';
$devkey = '';
$market_key = '';
$return_url = '';
$return_parameter = '';
$fail_url = '';
if (isset($_SESSION[LOGINPARAMETER_CALLBACK]))
{
$login = LoginCallbackInformation::CreateWithString($_SESSION[LOGINPARAMETER_CALLBACK]);
$scode = $login->scode;
$app_id = $login->app_id;
$devkey = $login->dev_key;
$market_key = $login->market_key;
$return_url = $login->return_url;
$return_parameter = $login->return_parameter;
$fail_url = $login->fail_url;
}
// 详细验证参数并记录调试信息
if (empty($scode) || empty($return_url) || empty($fail_url) || empty($app_id) || empty($devkey) || empty($market_key))
{
$missing_params = [];
if (empty($scode)) $missing_params[] = 'scode';
if (empty($return_url)) $missing_params[] = 'return_url';
if (empty($fail_url)) $missing_params[] = 'fail_url';
if (empty($app_id)) $missing_params[] = 'app_id';
if (empty($devkey)) $missing_params[] = 'devkey';
if (empty($market_key)) $missing_params[] = 'market_key';
$error_msg = '缺少必要参数: ' . implode(', ', $missing_params);
error_log("WeChat Login Callback - Missing parameters: " . $error_msg);
error_log("Session LOGINPARAMETER_CALLBACK exists: " . (isset($_SESSION[LOGINPARAMETER_CALLBACK]) ? 'Yes' : 'No'));
if (isset($_SESSION[LOGINPARAMETER_CALLBACK])) {
error_log("Session LOGINPARAMETER_CALLBACK content: " . $_SESSION[LOGINPARAMETER_CALLBACK]);
}
// 显示友好的错误页面,包含调试信息
echo '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>微信登录失败</title></head><body>';
echo '<h1>微信登录失败</h1>';
echo '<h2>错误详情</h2>';
echo '<p>错误代码: 10010</p>';
echo '<p>错误信息: ' . htmlspecialchars($error_msg) . '</p>';
echo '<h2>调试信息</h2>';
echo '<p>Session ID: ' . session_id() . '</p>';
echo '<p>Session状态: ' . (isset($_SESSION[LOGINPARAMETER_CALLBACK]) ? '已存储参数' : '未找到登录参数') . '</p>';
echo '<p>Code参数: ' . htmlspecialchars($code) . '</p>';
echo '<p>State参数: ' . htmlspecialchars($state) . '</p>';
echo '<h2>可能的解决方案</h2>';
echo '<ul>';
echo '<li>请确保从正确的微信登录链接进入</li>';
echo '<li>请确保浏览器支持Cookie</li>';
echo '<li>请尝试清除浏览器缓存后重新登录</li>';
echo '</ul>';
echo '<p><a href="/api/debug_weixin.php" target="_blank">查看详细调试信息</a></p>';
echo '<p><a href="javascript:history.back()">返回上一页</a></p>';
echo '</body></html>';
return;
}
// 检查微信授权参数
if (!$state || !$code) {
error_log("WeChat Login Callback - Missing auth parameters: code=$code, state=$state");
if (!empty($return_url)) {
error_log("WeChat Login Callback - Redirecting to return_url: $return_url");
header('Location: ' . $return_url);
exit();
} else {
error_log("WeChat Login Callback - No return_url available, showing error page");
echo '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>微信授权失败</title></head><body>';
echo '<h1>微信授权失败</h1>';
echo '<h2>错误详情</h2>';
echo '<p>错误代码: 10011</p>';
echo '<p>错误信息: 缺少微信授权参数code或state</p>';
echo '<h2>调试信息</h2>';
echo '<p>Code参数: ' . htmlspecialchars($code) . '</p>';
echo '<p>State参数: ' . htmlspecialchars($state) . '</p>';
echo '<h2>可能的解决方案</h2>';
echo '<ul>';
echo '<li>请确保通过正确的微信授权链接访问</li>';
echo '<li>请检查微信公众号配置是否正确</li>';
echo '<li>请尝试重新进行微信登录</li>';
echo '</ul>';
echo '<p><a href="/api/debug_weixin.php" target="_blank">查看详细调试信息</a></p>';
echo '<p><a href="javascript:history.back()">返回上一页</a></p>';
echo '</body></html>';
return;
}
}
$marketList = Sql::select('a.*')
->from('syweb_market a')
->where('a.market_key=?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
$this->forwardUrl($fail_url, (new returnObject(1, 10007, '指定的门店不存在或已经被删除'))->to_array());
$marketInfo = $marketList[0];
$account = array();
$account["key"] = $marketInfo["weixin_appid"];
$account["secret"] = $marketInfo["weixin_secret_appid"];
$weixin = new WeiXinAccount($account);
/// 通过授权获得的code去换取网页授权的Access_token和openId
$oauth = $weixin->getOauthInfo($code);
/// 假如没有获得openId则重新发起一次网页授权请求
if (is_error($oauth) || empty($oauth['openid']))
{
//if ($market_key == 'yulejia')
// file_put_contents('c:/2.txt', json_encode($oauth));
$state = 'ylsid-' . session_name();
// 设置授权的回调地址
///$callback = rawurlencode("http://" . $this::$domain . "/api/login/weixin/callback");
$callback = $this->getFullUrl('/api/login/weixin/callback');
// 返回网页非静默授权的授权访问地址
// 参数1回调页面地址
// 参数2重定向后会带上state参数开发者可以填写a-zA-Z0-9的参数值
// 最多128字节
$forward = $weixin->getOauthUserInfoUrl($callback, $state);
header('Location: ' . $forward);
exit;
}
$sid = "";
$pdo = $this->db;
/// 通过网页授权查询用户详细信息
$userinfo = $weixin->getOauthUserInfo($oauth['access_token'], $oauth['openid']);
/// 通过openId拉取用户信息判断用户是否关注了公众号
$baseUserInfo = $weixin->fansQueryInfo($oauth['openid'], $this->db, $pdo);
/// 根据openId和门店Key从数据库中查询全局用户信息
$fan = get_wechat_by_user_id($market_key, $userinfo['openid'], isset($userinfo['unionid']) ? $userinfo['unionid'] : '', $this->db);
$pdo->beginTransaction();
if (!empty($fan))
{
/// 假如数据库中已经存在全局用户信息
/// 查询粉丝对应的会员详细信息
$member = getWeixinUserByUId($fan['id'], $this->db);
if (!empty($userinfo['errcode']))
{
// 假如授权返回错误消息,则重新登录
$this->forwardUrl($fail_url, (new returnObject(1, 10011, '缺少state或code参数登录失败!'))->to_array());
}
else
{
if (!empty($baseUserInfo["errcode"]))
{
// 假如授权返回错误消息,则重新登录
$this->forwardUrl($fail_url, (new returnObject(1, 10012, '缺少state或code参数登录失败!'))->to_array());
}
else
{
if ($baseUserInfo["subscribe"] == 1)
{
$userinfo["subscribe"] = 1;
$userinfo["subscribe_time"] = $baseUserInfo["subscribe_time"];
}
else
{
$userinfo["subscribe"] = 0;
$userinfo["subscribe_time"] = 0;
}
}
}
$member['uid'] = $fan['id'];
$member['openid'] = $fan['openid'];
require_once __DIR__ . '/../../lib/emoji/emoji.php';
$member['nickname'] = emoji_docomo_to_unified($userinfo['nickname']);
$member['nickname'] = emoji_kddi_to_unified($member['nickname']);
$member['nickname'] = emoji_softbank_to_unified($member['nickname']);
$member['nickname'] = emoji_google_to_unified($member['nickname']);
/// 粉丝头像
if (!empty($userinfo['headimgurl']))
{
$member['headimgurl'] = rtrim($userinfo['headimgurl'], '0') . 132;
}
$member['sex'] = $userinfo['sex'];// 性别
$member['province'] = $userinfo['province'];// 所属省份
$member['city'] = $userinfo['city'];// 所属城市
$member['country'] = $userinfo['country'];// 所属国家
$member['privilege'] = is_array($userinfo['privilege']) ? json_encode($userinfo['privilege'], JSON_UNESCAPED_UNICODE) : $userinfo['privilege'];
$member['subscribe'] = $userinfo['subscribe'];// 粉丝是否关注
// 粉丝是否关注
$member['subscribe_time'] = $userinfo['subscribe_time'];
$member['unionid'] = isset($userinfo['unionid']) ? $userinfo['unionid'] : ''; // unionid
// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode, AUTHTYPE_WECHAT, $fan['openid'], $fan['unionid'], $market_key, $this->db, $pdo);
// 更新微信用户信息
updateWeixinUserInfo($member, $this->db, $pdo);
}
else
{
/// 假如数据库中还不存在对应的粉丝信息记录
/// 通过网页授权接口获得粉丝信息(无论关注或未关注)
$userinfo = $weixin->getOauthUserInfo($oauth['access_token'], $oauth['openid']);
if (!empty($userinfo['errcode']))
{
// 假如授权返回错误消息,则重新登录
$this->forwardUrl($fail_url, (new returnObject(1, 10011, '缺少state或code参数登录失败!'))->to_array());
}
else
{
// 通过openId拉取用户信息判断用户是否关注了公众号
$baseUserInfo = $weixin->fansQueryInfo($userinfo['openid'], $this->db, $pdo);
if (!empty($baseUserInfo["errcode"]))
{
// 假如授权返回错误消息,则重新登录
$this->forwardUrl($fail_url, (new returnObject(1, 10012, '缺少state或code参数登录失败!'))->to_array());
}
else
{
if ($baseUserInfo["subscribe"] == 1)
{
$userinfo["subscribe"] = 1;
$userinfo["subscribe_time"] = $baseUserInfo["subscribe_time"];
}
else
{
$userinfo["subscribe"] = 0;
$userinfo["subscribe_time"] = 0;
}
}
}
// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode, AUTHTYPE_WECHAT, $userinfo['openid'], isset($userinfo['unionid']) ? $userinfo['unionid'] : '', $market_key, $this->db, $pdo);
$userinfo['uid'] = $globalUserInfoId;// 全局用户ID
require_once __DIR__ . '/../../lib/emoji/emoji.php';
$userinfo['nickname'] = emoji_softbank_to_unified($userinfo['nickname']);
if (!empty($userinfo['headimgurl']))
{
// 粉丝头像
$userinfo['headimgurl'] = rtrim($userinfo['headimgurl'], '0') . 132;
}
///$userinfo['unionid'] = $userinfo['unionid']; // unionid
updateWeixinUserInfo($userinfo, $this->db, $pdo);
}
$pdo->commit();
// 新创建的全局用户信息从中获取新创建的sid
$globalUserInfo = getUserById($globalUserInfoId, $this->db);
$sid = $globalUserInfo["sid"];
$p = strstr($return_url, '?');
if (empty($p))
$return_url .= "?sid={$sid}&scode={$scode}{$return_parameter}";
elseif ('?' == $p)
$return_url .= "sid={$sid}&scode={$scode}{$return_parameter}";
else
$return_url .= "&sid={$sid}&scode={$scode}{$return_parameter}";
// 登录成功后跳转到客户端传入的回调页面
header('Location: ' . $return_url);
} catch (Exception $e) {
error_log("WeChat Login Callback Error: " . $e->getMessage() . "\n" . $e->getTraceAsString());
// 如果有失败回调URL跳转到失败页面
if (!empty($fail_url)) {
$this->forwardUrl($fail_url, (new returnObject(1, 10099, '微信登录处理失败: ' . $e->getMessage()))->to_array());
} else {
// 否则显示错误信息
echo '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>登录失败</title></head><body>';
echo '<h1>微信登录失败</h1>';
echo '<p>错误信息: ' . htmlspecialchars($e->getMessage()) . '</p>';
echo '<p><a href="javascript:history.back()">返回上一页</a></p>';
echo '</body></html>';
}
}
}
/**
* 使用微信授权登录
* @route({"GET","/weixin/silence"})
* @param({"appid","$._GET.appid"}) 应用appid
* @param({"devkey","$._GET.devkey"}) 开发者key
* @param({"market_key","$._GET.market_key"}) 门店key
* @param({"scode","$._GET.scode"}) 客户端生成的Scode
* @param({"target","$._GET.target"}) 客户端需要回调的地址
* @param({"state","$._POST.state"}) 随机参数
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function weixinUrlLogin($appid = "", $devkey = "", $market_key = "", $scode = "", $target = "", $state = '')
{
if (empty($appid))
return new returnObject(1, 10001, '未传入appid参数!');
if (empty($devkey))
return new returnObject(1, 10002, '未传入devkey参数!');
$devList = Sql::select('a.*')
->from('syweb_admin a')
->where('a.type=2 and a.admin_key=? and a.status=1', $devkey)
->get($this->db, null);
if (empty($devList) || count($devList) <= 0)
return new returnObject(1, 10003, 'devkey无效或未经过审核!');
$devInfo = $devList[0];
$appList = Sql::select('b.*')
->from('syweb_app_base a, syweb_app b')
->where('a.app_key = b.ref_key and a.status = b.status and a.dev_key = b.dev_key and a.ref_key = ? and a.dev_key = ? and a.status = 10', $appid, $devInfo['admin_key'])
->get($this->db, null);
if (empty($appList) || count($appList) <= 0)
return new returnObject(1, 10005, '指定的应用不存在或未被审核!');
$appInfo = $appList[0];
$marketList = Sql::select('a.*')
->from('syweb_market a, syweb_logintype_market b')
->where('a.market_key = b.market_key and b.type_key = \'0012\' and b.is_enabled != 0 and a.market_key = ?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
return new returnObject(1, 10007, '指定的门店不存在或已经被删除, 或该门店不支持该登录方式!');
$marketInfo = $marketList[0];
/// 剔除必须的参数.
$needed = array('sid', 'scode', 'appid', 'devkey', 'market_key', 'target', 'fail_target');
/// 获取请求参数
$refer_paramers = GetAttachParameters($needed);
$parameters = '';
foreach ($refer_paramers as $k => $v)
{
$parameters .= "&{$k}={$v}";
}
// 开启一个会话
session_start();
$_SESSION[LOGINPARAMETER_CALLBACK] = (new LoginCallbackInformation('', $scode, $appInfo['id'], $devkey, $marketInfo["market_key"], $target, $parameters, ''))->to_string();
///$callback = "http://" . $this::$domain . "/api/login/weixin/callback";
$callback = $this->getFullUrl('/api/login/weixin/silence/callback');
$state = 'ylsid-' . session_name();
$forward = $weixin->getOauthCodeUrl($callback, $state);
//exit($forward);
header('Location: ' . $forward);
exit();
/*
// 开启一个会话
session_start();
$_SESSION['user_app_id'] = $appInfo["id"];
$_SESSION['user_devkey'] = $devkey;
$_SESSION['user_market_id'] = $marketInfo["id"];
$_SESSION['user_target'] = $target;
$_SESSION['state'] = $state;
$callback = $this->getFullUrl('/api/login/weixin/callback_url');
$state = 'ylsid-' . session_name();
$forward = $weixin->getOauthCodeUrl($callback, $state);
header('Location: ' . $forward);
exit();
*/
}
/**
* 微信授权登录回调
* @route({"GET","/weixin/silence/callback"})
* @param({"code", "$._GET.code"})
* @param({"state", "$._GET.state"})
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function weixinLoginUrlCallback($code = '', $state = '')
{
session_start();
$scode = '';
$app_id = '';
$devkey = '';
$market_key = '';
$return_url = '';
$return_parameter = '';
$fail_url = '';
if (isset($_SESSION[LOGINPARAMETER_CALLBACK]))
{
$login = LoginCallbackInformation::CreateWithString($_SESSION[LOGINPARAMETER_CALLBACK]);
$scode = $login->scode;
$app_id = $login->app_id;
$devkey = $login->dev_key;
$market_key = $login->market_key;
$return_url = $login->return_url;
$return_parameter = $login->return_parameter;
$fail_url = $login->fail_url;
}
if (!$scode || !$return_url || !$app_id || !$devkey || !$market_key)
return new returnObject(1, 10006, '缺少必要参数,登录失败!');
if (!$state || !$code)
header('Location: ' . $return_url);
$marketList = Sql::select('a.*')
->from('syweb_market a')
->where('a.market_key=?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
return new returnObject(1, 10007, '指定的门店不存在或已经被删除!');
$marketInfo = $marketList[0];
$account = array();
$account["key"] = $marketInfo["weixin_appid"];
$account["secret"] = $marketInfo["weixin_secret_appid"];
$weixin = new WeiXinAccount($account);
/// 通过授权获得的code去换取网页授权的Access_token和openId
$oauth = $weixin->getOauthInfo($code);
// 假如没有获得openId则重新发起一次网页授权请求
if (is_error($oauth) || empty($oauth['openid']))
{
$state = 'ylsid-' . session_name();
// 设置授权的回调地址
$callback = $this->getFullUrl('/api/login/weixin/silence/callback');
// 返回网页非静默授权的授权访问地址
// 参数1回调页面地址
// 参数2重定向后会带上state参数开发者可以填写a-zA-Z0-9的参数值
// 最多128字节
$forward = $weixin->getOauthCodeUrl($callback, $state);
header('Location: ' . $forward);
exit;
}
/*// 根据openId和商家ID从数据库中查询全局用户信息
$fan = getUserByOpenId($market_id,$oauth['openid'],AUTHTYPE_WECHAT,$this->db);
$sid = "";
$pdo = $this->db;
$pdo->beginTransaction();
// 通过网页授权查询用户详细信息
$userinfo = $weixin->getOauthUserInfo($oauth['access_token'],$oauth['openid']);
// 通过openId拉取用户信息判断用户是否关注了公众号
$baseUserInfo = $weixin->fansQueryInfo($oauth['openid'],$this->db,$pdo);
if (!empty($fan)) {// 假如数据库中已经存在全局用户信息
// 查询粉丝对应的会员详细信息
$members = getWeixinUserByUId($fan['id'],$this->db);
if(!empty($userinfo["errcode"])){// 假如授权返回错误消息,则重新登录
header('Location: ' . $target);
}else{
if(!empty($baseUserInfo["errcode"])){// 假如授权返回错误消息,则重新登录
header('Location: ' . $target);
}else{
if( $baseUserInfo["subscribe"]==1 ){
$userinfo["subscribe"] = 1;
$userinfo["subscribe_time"] = $baseUserInfo["subscribe_time"];
}else{
$userinfo["subscribe"] = 0;
$userinfo["subscribe_time"] = 0;
}
}
}
$member["uid"] = $fan['id'];
$member["openid"] = $fan['openid'];
require_once __DIR__ . '/../../lib/emoji/emoji.php';
$member['nickname'] = emoji_docomo_to_unified($userinfo['nickname']);
$member['nickname'] = emoji_kddi_to_unified($member['nickname']);
$member['nickname'] = emoji_softbank_to_unified($member['nickname']);
$member['nickname'] = emoji_google_to_unified($member['nickname']);
// 粉丝昵称
//$member['nickname'] = stripslashes(stripcslashes($userinfo['nickname']));
if (!empty($userinfo['headimgurl'])) {// 粉丝头像
$member['headimgurl'] = rtrim($userinfo['headimgurl'], '0') . 132;
}
$member['sex'] = $userinfo['sex'];// 性别
$member['province'] = $userinfo['province'];// 所属省份
$member['city'] = $userinfo['city'];// 所属城市
$member['country'] = $userinfo['country'];// 所属国家
$member['privilege'] = is_array($userinfo['privilege']) ? json_encode($userinfo['privilege'], JSON_UNESCAPED_UNICODE) : $userinfo['privilege'];
$member['subscribe'] = $userinfo['subscribe'];// 粉丝是否关注
// 粉丝是否关注
$member['subscribe_time'] = $userinfo['subscribe_time'];
// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode,AUTHTYPE_WECHAT,$fan['openid'],$fan['unionid'],$market_id,$this->db,$pdo);
updateWeixinUserInfo($member, $this->db, $pdo);
} else {// 假如数据库中还不存在对应的粉丝信息记录
// 通过网页授权接口获得粉丝信息(无论关注或未关注)
$userinfo = $weixin->getOauthUserInfo($oauth['access_token'],$oauth['openid']);
if(!empty($userinfo["errcode"])){// 假如授权返回错误消息,则重新登录
header('Location: ' . $target);
}else{
// 通过openId拉取用户信息判断用户是否关注了公众号
$baseUserInfo = $weixin->fansQueryInfo($userinfo['openid'],$this->db,$pdo);
if(!empty($baseUserInfo["errcode"])){// 假如授权返回错误消息,则重新登录
header('Location: ' . $target);
}else{
if( $baseUserInfo["subscribe"]==1 ){
$userinfo["subscribe"] = 1;
$userinfo["subscribe_time"] = $baseUserInfo["subscribe_time"];
}else{
$userinfo["subscribe"] = 0;
$userinfo["subscribe_time"] = 0;
}
}
}
// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode,AUTHTYPE_WECHAT,$userinfo['openid'],isset($userinfo['unionid']) ? $userinfo['unionid'] : '',$market_id,$this->db,$pdo);
$userinfo['uid'] = $globalUserInfoId;// 全局用户ID
require_once __DIR__ . '/../../lib/emoji/emoji.php';
//$userinfo['nickname'] = emoji_docomo_to_unified($userinfo['nickname']);
//$userinfo['nickname'] = emoji_kddi_to_unified($userinfo['nickname']);
$userinfo['nickname'] = emoji_softbank_to_unified($userinfo['nickname']);
//$userinfo['nickname'] = emoji_google_to_unified($userinfo['nickname']);
//exit;
//$userinfo['nickname'] = stripslashes(stripcslashes($userinfo['nickname']));
if (!empty($userinfo['headimgurl'])) {// 粉丝头像
$userinfo['headimgurl'] = rtrim($userinfo['headimgurl'], '0') . 132;
}
updateWeixinUserInfo($userinfo, $this->db, $pdo);
}
$pdo->commit();
// 新创建的全局用户信息从中获取新创建的sid
/*$globalUserInfo = getUserById($globalUserInfoId,$this->db);
$sid = $globalUserInfo["sid"];*/
/// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode, AUTHTYPE_WECHAT, $oauth['openid'], $oauth['unionid'], $market_key, $this->db, $this->db);
// 更新微信用户信息
$member = [
'uid' => $globalUserInfoId,
'subscribe' => @$oauth['subscribe'],
'subscribe_time' => @$oauth['subscribe_time'],
'openid' => @$oauth['openid'],
'unionid' => @$oauth['unionid'],
];
$id = Sql::select('a.id')
->from('syweb_users_weixin a')
->where('a.uid=? and a.openid=?', $member["uid"], $member["openid"])
->get($this->db, null);
if (empty($id)) {
Sql::insertInto('syweb_users_weixin')->values($member)->exec($this->db);
} else {
Sql::update('syweb_users_weixin')->setArgs($member)->where('uid=? and openid=?', $member["uid"], $member["openid"])->exec($this->db);
}
/// 新创建的全局用户信息从中获取新创建的sid
$globalUserInfo = getUserById($globalUserInfoId, $this->db);
$sid = $globalUserInfo["sid"];
$p = strstr($return_url, '?');
if (empty($p))
$return_url .= "?sid={$sid}&scode={$scode}{$return_parameter}";
elseif ('?' == $p)
$return_url .= "sid={$sid}&scode={$scode}{$return_parameter}";
else
$return_url .= "&sid={$sid}&scode={$scode}{$return_parameter}";
// 登录成功后跳转到客户端传入的回调页面
header('Location: ' . $return_url);
exit;
}
/**
* 使用聚开心授权登录
* @route({"GET","/jkx"})
* @param({"appid","$._GET.appid"}) 应用appid
* @param({"devkey","$._GET.devkey"}) 开发者key
* @param({"market_key","$._GET.market_key"}) 门店key
* @param({"scode","$._GET.scode"}) 客户端生成的Scode
* @param({"target","$._GET.target"}) 客户端需要回调的地址
* @param({"fail_target","$._GET.fail_target"}) 发生错误时,客户端回调的页面
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function jkxLogin($appid = "", $devkey = "", $market_key = "", $scode = "", $target = "", $fail_target = "")
{
$result = array();
if (empty($appid))
{
$result["error"] = '1';
$result["error_code"] = 10001; // 未传入appid参数
$result["msg"] = "未传入appid参数";
$this->forwardUrl($fail_target, $result);
}
if (empty($devkey))
{
$result["error"] = '1';
$result["error_code"] = 10002; // 未传入devkey参数
$result["msg"] = "未传入devkey参数";
$this->forwardUrl($fail_target, $result);
}
$devList = Sql::select('a.*')
->from('syweb_admin a')
->where('a.type=2 and a.admin_key=? and a.status=1', $devkey)
->get($this->db, null);
if (empty($devList) || count($devList) <= 0)
{
$result["error"] = '1';
$result["error_code"] = 10003; // devkey无效
$result["msg"] = "devkey无效或未经过审核";
$this->forwardUrl($fail_target, $result);
}
$devInfo = $devList[0];
$appBaseList = Sql::select('a.*')
->from('syweb_app_base a')
->where('a.ref_key=? and a.dev_key=? and a.status=10', $appid, $devInfo['admin_key'])
->get($this->db, null);
if (empty($appBaseList) || count($appBaseList) <= 0)
{
$result["error"] = '1';
$result["error_code"] = 10004; // 指定的应用不存在或未被审核
$result["msg"] = "指定的应用不存在或未被审核";
$this->forwardUrl($fail_target, $result);
}
$appBaseKey = $appBaseList[0]["app_key"];
$appList = Sql::select('a.*')
->from('syweb_app a')
->where('a.ref_key=? and a.dev_key=? and a.status=10', $appBaseKey, $devInfo['admin_key'])
->get($this->db, null);
if (empty($appList) || count($appList) <= 0)
{
$result["error"] = '1';
$result["error_code"] = 10005; // 指定的应用不存在或未被审核
$result["msg"] = "指定的应用不存在或未被审核";
$this->forwardUrl($fail_target, $result);
}
$appInfo = $appList[0];
$marketList = Sql::select('a.*')
->from('syweb_market a')
->where('a.market_key=?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
{
$result["error"] = '1';
$result["error_code"] = 10007; // 指定的门店不存在
$result["msg"] = "指定的门店不存在或已经被删除";
$this->forwardUrl($fail_target, $result);
}
$marketInfo = $marketList[0];
$account = array();
$account["key"] = $marketInfo['weixin_appid'];
//$weixin = new WeiXinAccount($account);
/*
// 分析主域名中的参数 begin
$referUrls = parse_url($_SERVER['HTTP_REFERER']);
$callback_paramers = "";
if (!empty($referUrls['query']))
{
// 假如传入了参数
$callback_paramers_list = explode("&", $referUrls['query']);
if (!empty($callback_paramers_list) && count($callback_paramers_list) > 0)
{
foreach ($callback_paramers_list as $key => $value)
{
if (!strstr($value, 'appid=') &&
!strstr($value, 'devkey=') &&
!strstr($value, 'market_key=') &&
!strstr($value, 'scode=') &&
!strstr($value, 'target=') &&
!strstr($value, 'state=')
)
{
if (empty($callback_paramers))
{
$callback_paramers = $value;
}
else
{
$callback_paramers .= '&' . $value;
}
}
}
}
}
$newTarget = '';
$targetUrls = parse_url($target);
if (!empty($targetUrls))
{
$newTarget = $targetUrls['scheme'] . '://' . $targetUrls['host'] . ((!empty($targetUrls['port']) && $targetUrls['port'] != '80') ? ':' . $targetUrls['port'] : '') . $targetUrls['path'];
}
if (!empty($callback_paramers))
{
if (strstr($newTarget, '?'))
{
if (strstr($newTarget, '&'))
{
$newTarget .= '&' . $callback_paramers;
}
else
{
$newTarget .= $callback_paramers;
}
}
else
{
$newTarget .= '?' . $callback_paramers;
}
}
// 分析主域名中的参数
*/
/// 剔除必须的参数.
$needed = array('sid', 'scode', 'appid', 'devkey', 'market_key', 'target', 'fail_target');
/// 获取请求参数
$refer_paramers = GetAttachParameters($needed);
$parameters = '';
foreach ($refer_paramers as $k => $v)
{
$parameters .= "&{$k}={$v}";
}
// 开启一个会话
session_start();
$_SESSION[LOGINPARAMETER_CALLBACK] = (new LoginCallbackInformation('', $scode, $appInfo['id'], $devkey, $marketInfo["market_key"], $target, $parameters, $fail_target))->to_string();
///$callback = "http://" . $this::$domain . "/api/login/jkx/callback";
$callback = $this->getFullUrl('/api/login/jkx/callback');
//$state = 'ylsid-' . session_name();
$jkxParamers = array();
$jkxParamers["appid"] = "G3CI8FQF";
$jkxParamers["Appkey"] = "28de5f4a54cbbb62b2264ab555ff7f62";
//$secret = "ecd10d48daf3138b88727bc65ca3e0bd";
$jkxParamers["returnUrl"] = $callback;
$forward = "http://www.0792it.com/partnerApi/GetAccessToken.aspx";
$this->forwardUrl($forward, $jkxParamers);
}
/**
* 聚开心授权登录回调(10010-10030)
* @route({"GET","/jkx/callback"})
* @param({"spid", "$._GET.spid"})
* @param({"accessToken", "$._GET.accessToken"})
* @param({"uid", "$._GET.uid"}) uid
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function jkxLoginCallback($spid, $accessToken, $uid)
{
session_start();
$scode = '';
$app_id = '';
$devkey = '';
$market_key = '';
$return_url = '';
$return_parameter = '';
$fail_url = '';
if (isset($_SESSION[LOGINPARAMETER_CALLBACK]))
{
$login = LoginCallbackInformation::CreateWithString($_SESSION[LOGINPARAMETER_CALLBACK]);
$scode = $login->scode;
$app_id = $login->app_id;
$devkey = $login->dev_key;
$market_key = $login->market_key;
$return_url = $login->return_url;
$return_parameter = $login->return_parameter;
$fail_url = $login->fail_url;
}
if (!$scode || !$return_url || !$fail_url || !$app_id || !$devkey || !$market_key)
{
if (empty($fail_url))
exit('缺少必要参数,登录失败!');
else
$this->forwardUrl($fail_url, (new returnObject(1, 10010, '缺少必要参数,登录失败!'))->to_array());
}
if (!$spid || !$accessToken || !$uid)
{
if (empty($fail_url))
exit('缺少spid或accessToken或uid参数登录失败!');
else
$this->forwardUrl($fail_url, (new returnObject(1, 10011, '缺少spid或accessToken或uid参数登录失败!'))->to_array());
}
$marketList = Sql::select('a.*')
->from('syweb_market a')
->where('a.market_key=?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
{
$this->forwardUrl($fail_url, (new returnObject(1, 10007, '指定的门店不存在或已经被删除'))->to_array());
}
//$marketInfo = $marketList[0];
//$account = array();
//$account["key"] = $marketInfo["weixin_appid"];
//$account["secret"] = $marketInfo["weixin_secret_appid"];
//$weixin = new WeiXinAccount($account);
$appid = "G3CI8FQF";
$appkey = "28de5f4a54cbbb62b2264ab555ff7f62";
$url = "http://www.0792it.com/partnerApi/GetSpidFromUid.ashx?appid={$appid}&appkey={$appkey}&uid={$uid}";
$response = ihttp_get($url);
if (empty($response))
{
$this->forwardUrl($fail_url, (new returnObject(1, 10012, '获取授权信息错误,登录失败!'))->to_array());
}
$response = @json_decode($response['content'], true);
$spid = $response["spid"];
$accessToken = $response["accessToken"];
// 开始获取用户信息
$url = "http://www.0792it.com/partnerApi/GetUserInfo.ashx?spid={$spid}&accessToken={$accessToken}";
$sign = "accessToken={$accessToken}&spid={$spid}&secret=ecd10d48daf3138b88727bc65ca3e0bd";
$sign = md5($sign);
$url .= "&sign={$sign}";
$response = ihttp_get($url);
if (empty($response))
{
$this->forwardUrl($fail_url, (new returnObject(1, 10012, '获取授权信息错误,登录失败!'))->to_array());
}
$response = @json_decode($response['content'], true);
$retCode = $response["RetCode"];
if ($retCode == 1)
{
$this->forwardUrl($fail_url, (new returnObject(1, 10013, $response["RetMsg"]))->to_array());
}
$level = $response["Level"];
$enum = $response["Enum"];
$realname = $response["Realname"];
$img = $response["Img"];
$tel = $response["Tel"];
$integral = $response["Integral"];
// 根据openId和门店Key从数据库中查询全局用户信息
$fan = getUserByOpenId($market_key, $uid, AUTHTYPE_JKX, $this->db);
//$sid = "";
$pdo = $this->db;
$pdo->beginTransaction();
if (!empty($fan))
{
// 假如数据库中已经存在全局用户信息
// 查询粉丝对应的会员详细信息
$members = getJkxUserByUId($fan['id'], $this->db);
$member["uid"] = $fan['id'];
$member["username"] = $uid;
$member['headimgurl'] = $img;
$member['level'] = $level;
$member['enum'] = $enum;
$member['realname'] = $realname;
$member['tel'] = $tel;
$member['integral'] = $integral;
// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode, AUTHTYPE_JKX, $uid, '', $market_key, $this->db, $pdo);
// 更新微信用户信息
updateJkxUserInfo($member, $this->db, $pdo);
}
else
{
// 假如数据库中还不存在对应的粉丝信息记录
// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode, AUTHTYPE_JKX, $uid, '', $market_key, $this->db, $pdo);
$userinfo['uid'] = $globalUserInfoId;// 全局用户ID
$userinfo["username"] = $uid;
$userinfo['level'] = $level;
$userinfo['enum'] = $enum;
$userinfo['realname'] = $realname;
$userinfo['tel'] = $tel;
$userinfo['headimgurl'] = $img;
$userinfo['integral'] = $integral;
updateJkxUserInfo($userinfo, $this->db, $pdo);
}
$pdo->commit();
// 新创建的全局用户信息从中获取新创建的sid
$globalUserInfo = getUserById($globalUserInfoId, $this->db);
$sid = $globalUserInfo["sid"];
$p = strstr($return_url, '?');
if (empty($p))
$return_url .= "?sid={$sid}&scode={$scode}{$return_parameter}";
elseif ('?' == $p)
$return_url .= "sid={$sid}&scode={$scode}{$return_parameter}";
else
$return_url .= "&sid={$sid}&scode={$scode}{$return_parameter}";
// 登录成功后跳转到客户端传入的回调页面
header('Location: ' . $return_url);
}
/**
* 使用APP登录
* @route({"POST","/ylnn"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"market_key","$._POST.market_key"}) 门店key
* @param({"scode","$._POST.scode"}) 客户端生成的Scode
* @param({"agent_key","$._POST.agent_key"}) 代理商Key
* @param({"game_key","$._POST.game_key"}) 游戏Key
* @param({"user_key","$._POST.user_key"}) 用户Key
* @param({"headImg","$._POST.headImg"}) 用户头像
* @param({"nickname","$._POST.nickname"}) 用户昵称
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function ylnnLogin(
$appid = "",
$devkey = "",
$market_key = "",
$scode = "",
$agent_key = "",
$game_key = "",
$user_key = '',
$headImg = '',
$nickname = ''
)
{
if (empty($appid))
return new returnObject(1, 10001, '未传入appid参数!');
if (empty($devkey))
return new returnObject(1, 10002, '未传入devkey参数!');
$devList = Sql::select('a.*')
->from('syweb_admin a')
->where('a.type=2 and a.admin_key=? and a.status=1', $devkey)
->get($this->db, null);
if (empty($devList) || count($devList) <= 0)
return new returnObject(1, 10002, 'devkey无效或未经过审核!');
$devInfo = $devList[0];
/*
$appBaseList = Sql::select('a.*')
->from('syweb_app_base a')
->where('a.ref_key=? and a.dev_key=? and a.status=10', $appid, $devInfo['admin_key'])
->get($this->db, null);
if (empty($appBaseList) || count($appBaseList) <= 0)
return new returnObject(1, 10004, '指定的应用不存在或未被审核!');
$appBaseKey = $appBaseList[0]["app_key"];
$appList = Sql::select('a.*')
->from('syweb_app a')
->where('a.ref_key=? and a.dev_key=? and a.status=10', $appBaseKey, $devInfo['admin_key'])
->get($this->db, null);
if (empty($appList) || count($appList) <= 0)
return new returnObject(1, 10005, '指定的应用不存在或未被审核!');
*/
$appList = Sql::select('b.*')
->from('syweb_app_base a, syweb_app b')
->where('a.app_key = b.ref_key and a.status = b.status and a.dev_key = b.dev_key and a.ref_key = ? and a.dev_key = ? and a.status = 10', $appid, $devInfo['admin_key'])
->get($this->db, null);
if (empty($appList) || count($appList) <= 0)
return new returnObject(1, 10004, '指定的应用不存在或未被审核!');
///$appInfo = $appList[0];
$marketList = Sql::select('a.*')
->from('syweb_market a')
->where('a.market_key=?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
return new returnObject(1, 10007, '指定的门店不存在或已经被删除!');
///$marketInfo = $marketList[0];
$uid = md5($agent_key . $game_key . $user_key);
// 根据openId和门店Key从数据库中查询全局用户信息
$fan = getUserByOpenId($market_key, $uid, AUTHTYPE_NIUNIUGAME, $this->db);
$sid = "";
$pdo = $this->db;
$pdo->beginTransaction();
if (!empty($fan))
{
// 假如数据库中已经存在全局用户信息
// 查询粉丝对应的会员详细信息
$member = getYlnnUserByUId($fan['id'], $this->db);
$member['uid'] = $fan['id'];
$member['user_key'] = $uid;
$member['agent_key'] = $agent_key;
$member['game_key'] = $game_key;
$member['player_key'] = $user_key;
$member['headimgurl'] = $headImg;
$member['nickname'] = $nickname;
// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode, AUTHTYPE_NIUNIUGAME, $uid, '', $market_key, $this->db, $pdo);
// 更新微信用户信息
updateYlnnUserInfo($member, $this->db, $pdo);
}
else
{
// 假如数据库中还不存在对应的粉丝信息记录
// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode, AUTHTYPE_NIUNIUGAME, $uid, '', $market_key, $this->db, $pdo);
$userinfo['uid'] = $globalUserInfoId;// 全局用户ID
$userinfo['user_key'] = $uid;
$userinfo['agent_key'] = $agent_key;
$userinfo['game_key'] = $game_key;
$userinfo['player_key'] = $user_key;
$userinfo['headimgurl'] = $headImg;
$userinfo['nickname'] = $nickname;
updateYlnnUserInfo($userinfo, $this->db, $pdo);
}
$pdo->commit();
// 新创建的全局用户信息从中获取新创建的sid
$globalUserInfo = getUserById($globalUserInfoId, $this->db);
$sid = $globalUserInfo['sid'];
if (empty($sid))
return new returnObject(1, 13000, '登录失败无法获取SID!');
else
return new returnObject(0, 0, '登录成功!', array('sid' => $sid, 'scode' => $scode,));
}
/**
* 移动登录(微信)
* @route({"POST","/mobile/wechat"})
* @param({"appid","$._POST.appid"}) 应用appid
* @param({"devkey","$._POST.devkey"}) 开发者key
* @param({"market_key","$._POST.market_key"}) 门店key
* @param({"scode","$._POST.scode"}) 客户端生成的Scode
* @param({"open_id","$._POST.open_id"}) openid
* @param({"head_img","$._POST.head_img"}) 头像
* @param({"nick_name","$._POST.nick_name"}) 昵称
* @param({"sex","$._POST.sex"}) 性别
* @param({"city","$._POST.city"}) 城市
* @param({"province","$._POST.province"}) 省
* @param({"union_id","$._POST.union_id"}) unionid
* @throws({"phprs\util\exceptions\Forbidden","res", "403 Forbidden",{"error":"Forbidden"}}) cookie不可用
*/
public function mobile_wechat($appid = '', $devkey = '', $market_key = '', $scode = '', $open_id = '', $head_img = '', $nick_name = '', $sex = '', $city = '', $province = '', $union_id = '')
{
if (empty($appid))
return new returnObject(1, 10001, '未传入appid参数!');
if (empty($devkey))
return new returnObject(1, 10002, '未传入devkey参数!');
$devList = Sql::select('a.*')
->from('syweb_admin a')
->where('a.type=2 and a.admin_key=? and a.status=1', $devkey)
->get($this->db, null);
if (empty($devList) || count($devList) <= 0)
return new returnObject(1, 10002, 'devkey无效或未经过审核!');
$devInfo = $devList[0];
$appList = Sql::select('b.*')
->from('syweb_app_base a, syweb_app b')
->where('a.app_key = b.ref_key and a.status = b.status and a.dev_key = b.dev_key and a.ref_key = ? and a.dev_key = ? and a.status = 10', $appid, $devInfo['admin_key'])
->get($this->db, null);
if (empty($appList) || count($appList) <= 0)
return new returnObject(1, 10004, '指定的应用不存在或未被审核!');
///$appInfo = $appList[0];
$marketList = Sql::select('a.*')
->from('syweb_market a')
->where('a.market_key=?', $market_key)
->get($this->db, null);
if (empty($marketList) || count($marketList) <= 0)
return new returnObject(1, 10007, '指定的门店不存在或已经被删除!');
///$marketInfo = $marketList[0];
if (empty($open_id))
return new returnObject(1, 500, '用户open_id不能为空');
require_once __DIR__ . '/../../lib/emoji/emoji.php';
$nick_name = emoji_docomo_to_unified($nick_name);
$nick_name = emoji_kddi_to_unified($nick_name);
$nick_name = emoji_softbank_to_unified($nick_name);
$nick_name = emoji_google_to_unified($nick_name);
/// 根据openId和门店Key从数据库中查询全局用户信息
$fan = get_wechat_by_user_id($market_key, $open_id, $union_id, $this->db);
$pdo = $this->db;
$pdo->beginTransaction();
try
{
if (!empty($fan))
{
/// 假如数据库中已经存在全局用户信息
/// 查询粉丝对应的会员详细信息
$member = getWeixinUserByUId($fan['id'], $this->db);
$member['uid'] = $fan['id'];
$member['openid'] = $fan['openid'];
$member['nickname'] = $nick_name;
/// 粉丝头像
if (!empty($head_img))
$member['headimgurl'] = rtrim($head_img, '0') . 132;
$member['sex'] = $sex; /// 性别
$member['province'] = $province; /// 所属省份
$member['city'] = $city; /// 所属城市
$member['country'] = ''; /// 所属国家
$member['privilege'] = '';
$member['subscribe'] = 0; /// 粉丝是否关注
$member['subscribe_time'] = 0; /// 粉丝是否关注
$member['unionid'] = $union_id; // unionid
/// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode, AUTHTYPE_WECHAT, $fan['openid'], $fan['unionid'], $market_key, $this->db, $pdo);
/// 更新微信用户信息
updateWeixinUserInfo($member, $this->db, $pdo);
}
else
{
// 根据当前openId创建一条全局用户记录或更新用户记录
$globalUserInfoId = updateUserInfo($scode, AUTHTYPE_WECHAT, $open_id, $union_id, $market_key, $this->db, $pdo);
$member = array(
'uid' => $globalUserInfoId, /// 全局用户ID
'openid' => $open_id, /// openid
'nickname' => $nick_name, /// 昵称
'headimgurl' => !empty($head_img) ? rtrim($head_img, '0') . 132 : '', /// 头像
'sex' => $sex, /// 性别
'province' => $province, /// 所属省份
'city' => $city, /// 所属城市
'country' => '', /// 所属国家
'privilege' => '',
'subscribe' => 0, /// 粉丝是否关注
'subscribe_time' => 0, /// 关注时间
'unionid' => $union_id, // unionid
);
updateWeixinUserInfo($member, $this->db, $pdo);
}
$pdo->commit();
}
catch (Exception $Exception)
{
$pdo->rollBack();
return new returnObject($Exception->getCode(), $Exception->getCode(), $Exception->getMessage());
}
// 新创建的全局用户信息从中获取新创建的sid
$globalUserInfo = getUserById($globalUserInfoId, $this->db);
$sid = $globalUserInfo['sid'];
if (empty($sid))
return new returnObject(1, 13000, 'login failed, cannot query sid code value!');
else
return new returnObject(0, 0, 'success!', array('sid' => $sid, 'scode' => $scode,));
}
/** @inject("ioc_factory") */
private $factory;
/**
* @property({"default":"@db"})
* @var PDO
*/
public $db;
// 此处删除了代码
}