微信公众号静默授权注册及获取用户信息 - 长不大的菜鸟

时间:2024-02-16 19:30:48

微信公众号静默授权注册及获取用户信息

微信登陆包括两部分:1.常用的静默授权;2.获取用户身份信息 
开发环境: 
Thinkphp3.2.3beta+onethink、yershop 
新浪SAE服务器,点此注册 
认证微信服务号

静默授权

微信公众号授权登陆有两种,常用的一种为静默授权snsapi_base。下面讲它的实现代码 
开发文档:http://mp.weixin.qq.com/wiki/4/9ac2e7b1f1d22e9e57260f6553822520.html 
目标:获取用户openid 
假设我的微信登陆地址为 Wap/User/wxlogin()方法

基础配置

1.认证微信服务号 
2.接口权限:网页账号,填写自己要使用的域名(www.abc.com这样的) 
这里写图片描述 
这里写图片描述 
3.服务器后台添加配置字段:C(‘DOMAIN’) C(‘APPID’) C(‘AppSecret’),在代码中调用 
C(‘DOMAIN’),在yershop后台中为自动获取的域名地址 
C(‘APPID’),公众平台应用ID 
C(‘AppSecret’),公众平台密钥

获取code核心代码

//获取code代码
function createOauthUrlForCode($redirectUrl)
    {
        //lifan 
        $param [\'appid\'] =C(\'APPID\');
        $param [\'redirect_uri\'] = $redirectUrl. \'&getOpenId=1\';
        $param [\'response_type\'] = \'code\';
        $param [\'scope\'] = \'snsapi_base\';
        $param [\'state\'] = 123;
        $url = \'https://open.weixin.qq.com/connect/oauth2/authorize?\' . http_build_query ( $param ) . \'#wechat_redirect\';
        return $url;
    }

获取openid核心代码

function getOpenid()
    {
        $urlObj["appid"] = C(\'APPID\');
        $urlObj["secret"] = C(\'AppSecret\');
        $urlObj["code"] = I ( \'code\' );
        $urlObj["grant_type"] = "authorization_code";
        $url = \'https://api.weixin.qq.com/sns/oauth2/access_token?\' . http_build_query ( $urlObj );
        //初始化curl
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOP_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //运行curl,结果以jason形式返回
        $res = curl_exec($ch);
        curl_close($ch);
        //取出openid
        $data = json_decode($res,true);
        return $data[\'openid\'];
    }

获取用户信息

获取并保存基础access_token

/**
 * 获取基础 accesstoken
 * 7200秒过时
 * sae不可写,保存于数据库中
 * at表字段:id,accesstoken,lasttime
 */
function getAccesstoken(){
    $param[\'grant_type\'] = \'client_credential\';
    $param[\'appid\'] = C("APPID");
    $param[\'secret\'] = C("SECRET");
    $lastAT = M(\'at\')->find(1);
    $accesstoken = $lastAT[\'accesstoken\'];
    if(!$lastAT){
        M(\'at\') -> add(array(\'id\'=>1,\'accesstoken\'=>\'null\',\'lasttime\'=>0));
        $lastAT[\'lasttime\'] = 0;
    }
    $now = NOW_TIME;
    $timecha = $now - $lastAT[\'lasttime\'];
    if($timecha > 7200){
        $url = \'https://api.weixin.qq.com/cgi-bin/token?\' . http_build_query ( $param );
        $content = file_get_contents ( $url );
        $content = json_decode ( $content, true );
        $data[\'accesstoken\'] = $content[\'access_token\'];
        $data[\'lasttime\'] = NOW_TIME;
        M(\'at\')->where(array(\'id\'=>1))->save($data);
        $accesstoken = $content[\'access_token\'];
    }
    return $accesstoken;
}

获取用户信息

/**
 * 获取用户基本信息
 * openid:用户的openid。用户与公众号唯一身份标识
 * 若用户未关注公众号,无法获取详细信息
 */
function getWeixinInfo($openid) {
    $isWeixinBrowser = isWeixinBrowser ();
    if(!$isWeixinBrowser){
        return;
    }
    $param[\'access_token\'] = getAccesstoken();
    $param[\'openid\'] = $openid;
    $param[\'lang\'] = \'zh_CN\';
    $url = \'https://api.weixin.qq.com/cgi-bin/user/info?\' . http_build_query ( $param );
    $content = file_get_contents ( $url );
    $content = json_decode ( $content, true );
    return $content;
}

其它函数

// 判断是否是在微信浏览器里
function isWeixinBrowser() {
    $agent = $_SERVER [\'HTTP_USER_AGENT\'];
    if (! strpos ( $agent, "icroMessenger" )) {
        return false;
    }
    return true;
}
/**
 * ? or &
 * @param 原始地址 $urls
 * @param 添加参数 $parm
 * @param 参数值 $value
 * @return 带? 或 & 的参数
 */
function addurl($urls,$parm,$value=""){
    if(!strstr($urls, \'?\')){
        $adds = "?".$parm."=".$value;
    }else{
        $adds = "&".$parm."=".$value;
    }
    return $adds;
}

完整的微信登陆注册流程实现

功能均实现在一个方法里,请仔细按照序号查看流程

public function weilogin($url = \'\') {
/*(1)非微信浏览器,退回到普通登陆页*/
        if(!isWeixinBrowser()){
            redirect ( U ( \'/wap/user/login\' ) );
        }
        $openid = I(\'get.openid\');
        $Member = D ( "Member" );
/*(2)判断是否已经获取到了openid,否第(3)步*/
        if ($openid) {
/*(6)获取到了openid,判断member表是否存入用户的openid。存:非第一次注册登陆;没存:第一次注册登陆*/
            $weiuserinfo = M(\'member\')->where (array(\'openid\' => $openid))->find ();
/*(7)有用户信息:非第一次注册登陆*/
            if ($weiuserinfo) {
                if ($Member->login ( $weiuserinfo [\'uid\'] )) { // 登录用户
                  //在登陆前的页面,设置cookie(\'api_redirect\',U(\'Index.index\'))信息
                  $urls = cookie ( \'api_redirect\' );
                  //登录成功,跳转返回
                  redirect($urls);
                }else {
                    //登录异常,回到普通登陆页面
                    $this->error ( \'登录超时!\', U ( "/wap/user/login" ) );
                }
            } else {
/*(8)没有存入用户openid:第一次注册登陆*/
                /*根据openid获取微信用户信息*/
                $weiData = getWeixinInfo($openid);
                if (!empty($weiData[\'nickname\'])){
                    //设置用户名为用户微信昵称
                    $username=$weiData[\'nickname\'];
                }else{
                    /*当用户未关注无法拉取用户信息时,为用户起名为当前时间戳。也可以提示用户关注公众号,否则就普通登陆*/
                    $username=NOW_TIME;
                }
                //进行重名检测,用户昵称若重名,之后数据表也无法添加用户信息
                $ischong = M(\'ucenter_member\')->where(array(\'username\'=>$username))->find();
                if($ischong>0){
                    //发现有重复用户名,命名为昵称+时间戳,避免重名
                    $username = $username.NOW_TIME;
                }
                /* 调用注册接口注册用户 */
                $User = new UserApi ();
                // 返回ucentermember数据表用户主键id;设置默认密码:123456
                $uid = $User->register ( $username, \'123456\' );
                if (0 < $uid) { // UC登录成功
                    /* 登录用户;D(\'Member\')->login此操作实现向member表新增记录*/
                    if ($Member->login ( $uid, $_GET [\'openid\'] )) {
/*(9)登陆成功,回到设置的页面*/
                        redirect(cookie ( \'api_redirect\' ));
                    }
                } else {
                    //ucenter_member表注册失败,跳转到普通登陆页
                    $this->error ( \'登录超时!\', U ( "/wap/user/login" ) );
                }
            }
        } else {
/*(3)实现微信登陆获取openid*/
            if (! is_login ()) {
            $getopenId = I(\'get.getOpenId\');
            $state = I(\'get.state\');
            //此处组链接一定要细心,否则报redirect_uri错误信息。不要用手写的url
            $urls = C ( \'DOMAIN\' ) . U ( "/Wap/User/weilogin" );
/*(4)实现微信登陆第一步获取code,返回的链接参数含有$getopenId、$state信息*/
            if (!$getopenId){
                $url = substr ( $urls, 0, - 5 );//该操作将去掉.html
                // var_dump($url); //必要时检验
                $urlforcode = createOauthUrlForCode($url);
                redirect($urlforcode);
                }elseif($state){
/*(5)实现微信登陆第二步获取openid,返回openid;重新访问本函数,带上openid*/
                 $openid = getOpenId();    
                 redirect ( $urls . addurl($callback, "openid",$openid));        
                }
            }
        }
    }

至此,微信登陆篇完成。 
出处:blog.csdn.NET/afanxingzhou