首页 > 教程 >

PHP开发微信授权登录教程

2023-02-14教程围观

简介微信的授权登录和QQ、新浪等平台的授权登录都大同小异,均采用OauthOAuth2.0鉴权方式。微信授权分为两种:1、静默授权2、弹窗授权,需要用户手动同意两种scope的区别说明1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)2、以snsapi_userinfo为

  

微信的 授权登录和QQ、新浪等平台的授权登录都大同小异,均采用OauthOAuth2.0鉴权方式。


微信授权分为两种:

1、静默授权

2、弹窗授权,需要用户手动同意


两种scope的区别说明

1、以snsapi_ 为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)

2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。

用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。

具体而言,网页授权流程分为四步:

1、引导用户进入授权页面同意授权,获取code

2、通过code换取网页授权access_token(与基础支持中的access_token不同)

3、如果需要,开发者可以刷新网页授权access_token,避免过期

4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

以下是封装的微信操作类,需要用到两个数据表,用于保存access_token、ticket,由于他们具有一定有效期,且每天请求数有上限,所以开发者需自行保存,以下是代码:

<?php/***   微信操作表*   wxtoken 表结构*   id*   access_token*   addtime*   wxticket 表结构*   id*   ticket*   addtime*/class WX {    private $appid;    private $appserect;    private $curl;    private $msg;    protected $errs = array(        '-1' => '系统繁忙,此时请开发者稍候再试',        '0' => '请求成功',        '40001' => 'AppSecret错误或者AppSecret不属于这个公众号,请开发者确认AppSecret的正确性',        '40002' => '请确保grant_type字段值为client_credential',        '40164' => '调用接口的IP地址不在白名单中,请在接口IP白名单中进行设置。',    );    function __construct($appid, $appserect) {        $this->appid = $appid;        $this->appserect = $appserect;        $this->curl = new Curl();    }    /*    微信网页授权登录  需要在公众号设置 - 功能设置 - 网页授权域名    第一步:用户同意授权,获取code    scope : snsapi_  只能获取openid 直接跳转    snsapi_userinfo    */    public function getCode($redirect_uri, $scope = 'snsapi_userinfo',$state = '1') {        $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->appid}&redirect_uri={$redirect_uri}&response_type=code&scope={$scope}&state={$state}#wechat_redirect";        header("Location:{$url}");        exit;    }    /*    第二步:通过code换取网页授权access_token    */    public function getAccessTokenByCode($code) {        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->appid}&secret={$this->appserect}&code={$code}&grant_type=authorization_code";        // exit($url);        // $curl = new Curl();        $result = $this->curl->doGet($url);        if (!$result) {            // $this->curl->getError()            $this->msg = "获取token失败";            return false;        }        $result = json_decode($result, true);        if ($result['errcode']) {            $this->msg = $result['errmsg'];            return false;        }        return $result;    }    // 第三步:刷新access_token(如果需要) 通过code 获取openid $type 0静默授权 1弹窗授权    public function getUserInfo($code, $type = 0, $lang = 'zh_CN ') {        $result = $this->getAccessTokenByCode($code);            if (!$result) {            return false;        }        $member = C::t(PT_USER)->getByOpenid($result['openid']);    if ($member) {        return $member;    } else {        if ($type) {            $url = "https://api.weixin.qq.com/sns/userinfo?access_token={$result['access_token']}&openid={$result['openid']}&lang={$lang}";            // $return = $this->curl->doGet($url);            // 这接口有病 强制显示文件头            $return = file_get_contents($url);            if (!$return) {                $this->msg = '获取用户信息失败';                return false;            }            $return = json_decode($return, true);            if (!$return) {                $this->msg = '获取用户信息返回失败';                return false;            }            // file_put_contents('ccc.txt',print_r($return,true),FILE_APPEND);            $data = array(                'openid' => $return['openid'],                'name' => $return['nickname'],                'sex' => $return['sex'],                'province' => $return['province'],                'city' => $return['city'],                'country' => $return['country'],                'img' => $return['headimgurl'],                'bindtel' => 0,            );        } else {            $data = array(                'openid' => $result['openid'],                'username' => "微信用户_" . random(6,1)            );        }        $name = rand(100000, 1000000000);        $e = $name . "@qq.com";        $password = $e;        $id = UserAddEdit(0, $data['username'], $password, $e,10,0,"", $msg);        if ($id <= 0) {            $this->msg = $msg;            return false;        }        C::t(PT_USER)->update($data, $id);        $member = C::t(PT_USER)->get($id);        return $member;        }    }    /*    公众号 安全中心 设置IP白名单    公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。    */    public function getAccessToken($type) {        $addtime = TIMESTAMP - 7200;        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appid}&secret={$this->appserect}";        $row = C::t(PT_WXTOKEN)->getNew($addtime, $type);        if ($row) {            return $row['access_token'];        } else {            $result = $this->curl->doGet($url);            if (!$result) {                $this->msg = "无法获取令牌内容";                return false;            }            $result = json_decode($result, true);            if (!$result) {                $this->msg = "解析令牌内容失败";                return false;            }            if ($result['access_token']) {                C::t(PT_WXTOKEN)->addToken($result['access_token'], $type);                return $result['access_token'];            } else {                $this->msg = "获取令牌失败";                return false;            }        }    }    // 获取js票据  需要在公众号设置 - 功能设置 - JS接口安全域名设置    public function getJsTicket() {        $addtime = TIMESTAMP - 7200;        $row = C::t(PT_WXTICKET)->getNew($addtime);        if ($row) {            return $row['ticket'];        } else {            $token = $this->getAccessToken();            if (!$token) {                return false;            }            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$token}&type=jsapi";            $result = $this->curl->doGet($url);            if (!$result) {                $this->msg = "无法获取js票据";                return false;            }            $result = json_decode($result, true);            if (!$result) {                $this->msg = "解析js票据内容失败";                return false;            }            if ($result['ticket']) {                C::t(PT_WXTICKET)->addTicket($result['ticket']);                return $result['ticket'];            } else {                $this->msg = "获取js票据失败";                return false;            }        }    }    // js sdk 票据签名 当前网页的URL,不包含#及其后面部分    public function jsSign($data) {        // 1.所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)        ksort($data);        // 2.URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1 采用原始值,不进行URL 转义        $string1 = $this->ToUrlParams($data);        // echo "string1:{$string1}<br/>";        // 3.对string1做sha1加密        $sign = sha1($string1);        // echo "signature:{$sign}<br/>";        return $sign;    }    // 获取消息内容    public function getMsg() {        return $this->msg;    }    /**    * 格式化参数格式化成url参数    */    public function ToUrlParams($data) {        $buff = "";        foreach ($data as $k => $v) {            if ($k != "sign" && $v != "" && !is_array($v)) {                $buff .= $k . "=" . $v . "&";            }        }        $buff = trim($buff, "&");        return $buff;    }}?>

业务代码:

// 微信登录function wxlogin() {    global $_G,$identifier,$config,$wx;    if (!$_G['uid']) {        if ($_GET['state']) {            //回调            $member = $wx->getUserInfo($_GET['code']);            if (!$member) {                exit($wx->getMsg());            }            if (!function_exists("setloginstatus")) {                include_once libfile('function/member');            }            // 设置登录状态$wx            setloginstatus($member, 2592000);            checkfollowfeed();            $_G['uid'] = $member['uid'];            $_G['member'] = $member;        } else {            //请求授权 对参数编码            $redirect = urlencode(getProtocol() . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);            $wx->getCode($redirect, 'snsapi_ ');        }    }}function getProtocol() {    return is_HTTPS() ? 'https://' : 'http://';}function is_HTTPS() {  if ($_SERVER['HTTPS'] === 1 || $_SERVER['HTTPS'] === 'on' || $_SERVER['SERVER_PORT'] == 443) {        return true;    }    return false;}


下载链接:网站源码/小程序源码/网站模板下载

Tags: PHP 微信 登录 教程 开发