Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解`
微信授权登录
日期:2019-4-5 阿珏 折腾代码 浏览:1874次 评论:1条
文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319微信的授权登录和QQ、新浪等平台的授权登录都大同小异,均采用OauthOAuth2.0鉴权方式。
微信授权分为两种:
- 静默授权
- 弹窗授权,需要用户手动同意
两种scope的区别说明
具体而言,网页授权流程分为四步:
- 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
- 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
具体而言,网页授权流程分为四步:
- 引导用户进入授权页面同意授权,获取code
- 通过code换取网页授权access_token(与基础支持中的access_token不同)
- 如果需要,开发者可以刷新网页授权access_token,避免过期
- 通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
<?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();}/*微信网页授权登录 需要在公众号设置 - 功能设置 - 网页授权域名第一步:用户同意授权,获取codescope : snsapi_base 只能获取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');}// 设置登录状态$wxsetloginstatus($member, 2592000);checkfollowfeed();$_G['uid'] = $member['uid'];$_G['member'] = $member;} else {//请求授权 对参数编码$redirect = urlencode(getProtocol() . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);$wx->getCode($redirect, 'snsapi_base');}} } 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; }
网友评论:
头条新闻 2年前 (2019-04-11)
文章不错支持一下吧