步驟:
(原理:利用付費微信密鑰(appId和appSecret)請求微信服務器進行獲取用戶信息,進行用戶識別和一系列自定義操作)
1,申請開發帳號,或者微信公眾帳號,獲取appId和appSecret(https://open.weixin.qq.com,https://mp.weixin.qq.com);
2,添加微信登錄按鈕;
3,新建微信登錄按鈕關聯的方法(通過appId+scope+state請求微信服務器,獲取二維碼);
4,用戶掃描,授權登錄(用戶允許,則以get形式返回code值至redirectUrl(需urlencode函數處理));
5,通過appId+appSecret+code+grantType請求微信服務器,獲取accessToken,refreshToken,openid和unionid;
6,通過accessToken+openid獲取微信用戶更詳細信息(暱稱,地址等微信個人資料)
6,根據用戶unionid(或者openid),進行查庫寫庫等操作(抽取關聯會員的信息,或者引導註冊,綁定);
8,登錄處理,更新session。
//==================================================
//*****例子*****
//==================================================
if (empty($_SESSION['user_id'])) {
session_start();
}
/*微信授权登录,BY TC*/
$code=$_GET['code'];
$state=$_GET['state'];
/*直接访问通道:localhost/index.php?status=1*/
if (empty($_POST) && $_GET['wechatLogin']==1) {
$smarty->display('wechatLoginRegister.dwt');
die;
}
// $code='001d21c290fed10b36571d14c1af521B';
// $state='HCM';
/*
1.通过code换取accessToken,openid,unionid
2.缓存accessToken
3.设置自动续期accessToken
4.通过accessToken,openid换取用户信息
5.创建用户账号
6.更新wechatUser表(除openid字段)
7.更新入库
8.登陆处理,写入session
*/
if (!empty($code) && strlen($code)==32 && $state=='HCM' && $_SESSION[$code]!=='codeUsed') {
$_SESSION[$code]='codeUsed';
//==================================================
//开发号配置信息
$appId='xxxxxxxxxx';
$appSecret='xxxxxxxxxx';
$scope='snsapi_login';
$grantType='authorization_code';
//==================================================
//通过code换取accessToken,openid,unionid
/*
格式如下:
{"access_token":"OezXcEiiBSKSxW0eoylIeBBa9SjEhBMYFCNVmwsHT4OivCEZb3GXb68Y7TmvRgX4tCnKzcip4xEif8SNVokudWZHVtH26ril8BK9G4mW0B50u1VPGLfQEjY-zHXc-peV9d1ExnZs_tod2l61Wga6wQ","expires_in":7200,"refresh_token":"OezXcEiiBSKSxW0eoylIeBBa9SjEhBMYFCNVmwsHT4OivCEZb3GXb68Y7TmvRgX45OWgy247XTYI-yJ_atddI1oiyKX4FfF_g8rr06EXaGiCi7syrubS1tE_NgBK7MunIvo62gHIHyppZitswrNEmw","openid":"oo6uCw1O9zv1xkMBPwZ9PEPVXmVU","scope":"snsapi_login","unionid":"oMMW4wSZMVPy3KWXSnNL2bgeYWCw"}
--------------------------------------------------
{
"access_token":"OezXcEiiBSKSxW0eoylIeBBa9SjEhBMYFCNVmwsHT4OivCEZb3GXb68Y7TmvRgX4tCnKzcip4xEif8SNVokudWZHVtH26ril8BK9G4mW0B50u1VPGLfQEjY-zHXc-peV9d1ExnZs_tod2l61Wga6wQ",
"expires_in":7200,
"refresh_token":"OezXcEiiBSKSxW0eoylIeBBa9SjEhBMYFCNVmwsHT4OivCEZb3GXb68Y7TmvRgX45OWgy247XTYI-yJ_atddI1oiyKX4FfF_g8rr06EXaGiCi7syrubS1tE_NgBK7MunIvo62gHIHyppZitswrNEmw",
"openid":"oo6uCw1O9zv1xkMBPwZ9PEPVXmVU",
"scope":"snsapi_login",
"unionid":"oMMW4wSZMVPy3KWXSnNL2bgeYWCw"
}
*/
$url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$appId."&secret=".$appSecret."&code=".$code."&grant_type=".$grantType;
$codeJson=httpGet($url);
//缓存accessToken(省略)
$codeInfo=(array)json_decode($codeJson);
//通过accessToken,openid换取用户信息
$url="https://api.weixin.qq.com/sns/userinfo?access_token=".$codeInfo['access_token']."&openid=".$codeInfo['openid'];
$wechatUserJson=httpGet($url);
//判断是否新用户
$wechatUserInfo=(array)json_decode($wechatUserJson);
$userId=$GLOBALS['db']->getOne('SELECT ect_uid FROM '.$GLOBALS['ecs']->table('wechat_user')."WHERE unionid='".$wechatUserInfo['unionid']."'");
if($userId){
$username=$GLOBALS['db']->getOne('SELECT user_name FROM '.$GLOBALS['ecs']->table('users')."WHERE user_id='".$userId."'");
//直接登录,信息写入
$sessionId=md5(uniqid(mt_rand(), true));
$GLOBALS['db']->query('INSERT INTO '.$GLOBALS['ecs']->table('sessions')." (sesskey, expiry, ip, user_rank,data) VALUES ('".$sessionId. "', '".gmtime()."', '".$_SERVER['REMOTE_ADDR']."',4,'a:0:{}')");
$_SESSION['user_id']=$userId;
$_SESSION['user_name']=$username;
update_user_info();
recalculate_price();
$ucdata = isset($user->ucdata)? $user->ucdata : '';
$user_info=array('username'=>$username);
$smarty->assign('user_info',$user_info);
header('location:http://www.haocaimao.com');
die;
}else{
$_SESSION['unionid']=$wechatUserInfo['unionid'];
$smarty->display('wechatLoginRegister.dwt');
die;
}
}
/*异步,用户名称,唯一性检测*/
$usernameCheck=$_POST['usernameCheck'];
if(!empty($usernameCheck)){
$sql = "SELECT user_id FROM".$GLOBALS['ecs']->table('users')." WHERE user_name='".$usernameCheck."'";
$userId=$GLOBALS['db']->getOne($sql);
if ($userId) {
$bool='';
}else{
$bool=true;
}
echo json_encode($bool);
die;
}
/*异步,手机号码,唯一性检测*/
$mobileCheck=$_POST['mobileCheck'];
if(!empty($mobileCheck)){
$sql = "SELECT user_id FROM".$GLOBALS['ecs']->table('users')." WHERE mobile_phone='".$mobileCheck."'";
$userId=$GLOBALS['db']->getOne($sql);
if ($userId) {
$bool='';
}else{
$bool=true;
}
echo json_encode($bool);
die;
}
/*异步,快速注册,并登录*/
$username=$_POST['username'];
$password=$_POST['password'];
$rePassword=$_POST['rePassword'];
$mobile=$_POST['mobile'];
$verifyPost=$_POST['verifyPost'];
if(!empty($username) && !empty($password) && !empty($mobile)){
$sql = "SELECT verifycode,dateline FROM ".$GLOBALS['ecs']->table('verify_code')." WHERE mobile='".$mobile."' ORDER BY dateline DESC";
$verifyInfo=$GLOBALS['db']->getRow($sql);
$timeDiff=time()-$verifyInfo['dateline'];
if ($verifyPost!=$verifyInfo['verifycode'] || $timeDiff>86400){
echo json_encode('验证码错误');
die;
}else{
//新用户注册
$salt=mt_rand(1,9999);
$md5Password=md5(md5($password).$salt);
$regiTime=time();
$sql = "INSERT INTO ".$GLOBALS['ecs']->table('users')."(user_name,password,reg_time,ec_salt,mobile_phone) VALUES('$username','$md5Password','$regiTime',$salt,$mobile)";
$bool=$GLOBALS['db']->query($sql);
if ($bool) {
$sql = "SELECT user_id FROM ".$GLOBALS['ecs']->table('users')." WHERE user_name='".$username."'";
$ectUid=$GLOBALS['db']->getOne($sql);
//更新wechatUser表
$unionid=$_SESSION['unionid'];
$sql = "INSERT INTO ".$GLOBALS['ecs']->table('wechat_user')."(wechat_id,unionid,ect_uid) VALUES('1','$unionid','$ectUid')";
$bool=$GLOBALS['db']->query($sql);
//登陆信息写入
$sessionId=md5(uniqid(mt_rand(), true));
$GLOBALS['db']->query('INSERT INTO '.$GLOBALS['ecs']->table('sessions')." (sesskey, expiry, ip, user_rank,data) VALUES ('".$sessionId. "', '".gmtime()."', '".$_SERVER['REMOTE_ADDR']."',4,'a:0:{}')");
$_SESSION['user_id']=$ectUid;
$_SESSION['user_name']=$username;
update_user_info();
recalculate_price();
$ucdata = isset($user->ucdata)? $user->ucdata : '';
$user_info=array('username'=>$username);
$smarty->assign('user_info',$user_info);
}
}
}
/*异步,绑定账号*/
$bindUsername=$_POST['bindUsername'];
$bindPassword=$_POST['bindPassword'];
$bindCaptcha=$_POST['bindCaptcha'];
if(!empty($bindUsername) && !empty($bindUsername) && !empty($bindCaptcha)){
if(strtolower($bindCaptcha)==strtolower($_SESSION['captcha'])){
$ecSalt=$GLOBALS['db']->getOne("SELECT ec_salt FROM ".$GLOBALS['ecs']->table('users')." WHERE user_name='".$bindUsername."'");
if($ecSalt){
$userId=$GLOBALS['db']->getOne("SELECT user_id FROM ".$GLOBALS['ecs']->table('users')." WHERE user_name='".$bindUsername."' AND password='".md5(md5($bindPassword).$ecSalt)."'");
//帐号密码正确
if($userId){
$uid=$GLOBALS['db']->getOne("SELECT uid FROM ".$GLOBALS['ecs']->table('wechat_user')." WHERE ect_uid='".$userId."'");
if($uid){
echo json_encode('该帐号已被绑定');
die;
}else{
$unionid=$_SESSION['unionid'];
$sql = "INSERT INTO ".$GLOBALS['ecs']->table('wechat_user')."(wechat_id,unionid,ect_uid) VALUES('1','$unionid','$userId')";
$GLOBALS['db']->query($sql);
//登陆信息写入
$sessionId=md5(uniqid(mt_rand(), true));
$GLOBALS['db']->query('INSERT INTO '.$GLOBALS['ecs']->table('sessions')." (sesskey, expiry, ip, user_rank,data) VALUES ('".$sessionId. "', '".gmtime()."', '".$_SERVER['REMOTE_ADDR']."',4,'a:0:{}')");
$_SESSION['user_id']=$userId;
$_SESSION['user_name']=$bindUsername;
update_user_info();
recalculate_price();
$ucdata = isset($user->ucdata)? $user->ucdata : '';
$user_info=array('username'=>$bindUsername);
$smarty->assign('user_info',$user_info);
die;
}
}else{
echo json_encode('密码错误');
die;
}
}else{
echo json_encode('帐号不存在');
die;
}
}else{
echo json_encode('验证码错误');
die;
}
}
function httpGet($url){
$oCurl = curl_init();
if(stripos($url,"https://")!==FALSE){
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1);
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if(intval($aStatus["http_code"])==200){
return $sContent;
}else{
return false;
}
}