PHP开发微信授权登录操作办法

时间:20-03-18 03:11 责任编辑: admin 来源:电脑吧 点击:

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

  微信授权分为两种:

  1、静默授权

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

  两种scope的区别说明

  1、以snsapi_base为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_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,不包含#及其后面部分

最新更新

视觉焦点

新闻排行

  1. Win xp开机无桌面图标怎么办?
  2. WinXP怎么样防止匿名用户登录?
  3. Winxp删除用户之后加密文件打不开怎么办?
  4. Win XP桌面快捷键变成.lnk文件如何解决?
  5. 怎么样删除IE工具栏上其他网站链接呢?
  6. Winxp系统netcfg.hlp文件丢失找不到如何解决?
  7. WinXP桌面图标存在着蓝色阴影如何修复?
  8. XP电脑文件名变成蓝色了怎么回事?
  9. winxp如何取消开机磁盘扫描?
  10. 解决activex部件不能创建对象的两个办法