心理咨询网
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <?php
  2. /**
  3. * @copyright (C)2016-2099 Hnaoyun Inc.
  4. * @author XingMeng
  5. * @email hnxsh@foxmail.com
  6. * @date 2019年05月27日
  7. * 微信网页授权
  8. */
  9. namespace core\weixin;
  10. use core\basic\Config;
  11. class WxWebAuth
  12. {
  13. protected $appid;
  14. protected $secret;
  15. protected $noncestr;
  16. protected $redirect;
  17. protected $snsapi = 'snsapi_userinfo';
  18. public function __construct()
  19. {
  20. $this->appid = Config::get('weixin_appid');
  21. $this->secret = Config::get('weixin_secret');
  22. $this->noncestr = get_uniqid();
  23. $this->redirect = Config::get('weixin_redirect');
  24. }
  25. // 获取授权
  26. public function getAuthUser()
  27. {
  28. if (! ! $code = get('code')) { // 如果有code参数,意味重新授权方式获取数据,(在用户点击同意授权后跳转地址带code参数)
  29. $result = $this->getAccessToken($code); // 获取网页授权access_token
  30. $wx_user = $this->getAuthUserInfo($result->access_token, $result->openid);
  31. } else {
  32. // 在系统调取微信授权时,先检查是否已经缓存并且有效,如果无效则试着刷新,如果刷新失败则重新授权获取
  33. if (($token = session('weixin_web_access_token')) && ($openid = session('weixin_web_openid')) && $this->checkAccessToken($token, $openid)) { // 未过期,直接获取
  34. $wx_user = $this->getAuthUserInfo($token, $openid);
  35. } elseif (! ! $refresh_token = session('auth_refresh_token') && $result = $this->refreshAccessToken($refresh_token)) { // 刷新后获取
  36. $wx_user = $this->getAuthUserInfo($result->access_token, $result->openid);
  37. } else { // 重新授权
  38. $this->redirectWebAuth(get_current_url());
  39. exit();
  40. }
  41. }
  42. return $wx_user;
  43. }
  44. // 执行网页授权登录,返回指定地址
  45. private function redirectWebAuth($redirectUrl)
  46. {
  47. if (strpos($redirectUrl, 'http') === FALSE) {
  48. $http_type = is_https() ? 'https://' : 'http://';
  49. $redirectUrl = $http_type . $_SERVER['HTTP_HOST'] . $redirectUrl;
  50. }
  51. $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->appid}&redirect_uri=$redirectUrl&response_type=code&scope=" . $this->snsapi . "&state=weixin#wechat_redirect";
  52. header('Location:' . $url);
  53. }
  54. // 获取网页授权后用户信息,传递用户令牌及用户识别码
  55. private function getAuthUserInfo($token, $openid)
  56. {
  57. $url = "https://api.weixin.qq.com/sns/userinfo?access_token=$token&openid=$openid&lang=zh_CN";
  58. $result = json_decode(get_url($url));
  59. if (isset($result->errcode) && $result->errcode) {
  60. error('获取用户基础信息发生错误,请关闭后重新进入,错误:' . $result->errmsg);
  61. }
  62. return $result;
  63. }
  64. // 获取微信网页授权token,这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同
  65. private function getAccessToken($code)
  66. {
  67. $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->appid}&secret={$this->secret}&code=$code&grant_type=authorization_code";
  68. $result = json_decode(get_url($url));
  69. if (isset($result->errcode) && $result->errcode) {
  70. error('获取用户网页登录授权令牌发生错误,请关闭后重新进入,错误:' . $result->errmsg);
  71. }
  72. // 因为此access_token每个访问用户不同,这里用session来缓存
  73. session('weixin_web_access_token', $result->access_token);
  74. session('weixin_web_refresh_token', $result->refresh_token);
  75. session('weixin_web_openid', $result->openid);
  76. return $result;
  77. }
  78. // 检验微信网页授权access_token是否有效
  79. private function checkAccessToken($token, $openid)
  80. {
  81. $url = "https://api.weixin.qq.com/sns/auth?access_token=$token&openid=$openid";
  82. $result = json_decode(get_url($url));
  83. if (isset($result->errcode) && $result->errcode) {
  84. return false;
  85. } else {
  86. return true;
  87. }
  88. }
  89. // 刷新微信网页授权token,传递用户上一次获取的刷新令牌
  90. private function refreshAccessToken($refreshToken)
  91. {
  92. $url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid={$this->appid}&grant_type=refresh_token&refresh_token=$refreshToken";
  93. $result = json_decode(get_url($url));
  94. if (isset($result->errcode) && $result->errcode) {
  95. return false;
  96. }
  97. session('weixin_web_access_token', $result->access_token);
  98. session('weixin_web_refresh_token', $result->refresh_token);
  99. session('weixin_web_openid', $result->openid);
  100. return $result;
  101. }
  102. }