快乐每一天

自己选择的路,跪着也要走下去...

标签 微信授权登录 下的文章

基于ThinkPHP5微信H5授权登录获取用户信息(改进版)

不需要在网上找什么乱七八糟的东西,直接来之即用岂不是很完美。

只需要有一台服务器即可,没备案都可以玩这个功能。不需要拥有服务号,看完全文你就明白了。

数据库篇:

-- Adminer 4.6.3 MySQL dump

SET NAMES utf8;
SET time_zone = '+00:00';
SET foreign_key_checks = 0;
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';

DROP TABLE IF EXISTS `yy_wxuser`;
CREATE TABLE `yy_wxuser` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `nickname` varchar(255) DEFAULT '' COMMENT '昵称',
  `openid` varchar(255) DEFAULT '' COMMENT 'openid',
  `avatar` varchar(255) DEFAULT '' COMMENT '头像',
  `gender` tinyint(1) unsigned DEFAULT '1' COMMENT '性别',
  `province` varchar(20) DEFAULT '0' COMMENT '省',
  `city` varchar(20) DEFAULT '0' COMMENT '市',
  `county` varchar(20) DEFAULT '0' COMMENT '县',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='用户表';


-- 2019-04-20 03:13:42

基本库,用于调起授权授权获取用户信息 Wxgetuserinfo.php

<?php
/**
 * Created by PhpStorm.
 * User: wudi
 * Date: 2019/1/28
 * Time: 10:31
 */

namespace app\card\controller;
use think\Db;

class Wxgetuserinfo
{
    /**
     * 调用方法
     * 具体参考tp5的命名空间  https://www.kancloud.cn/manual/thinkphp5/118014
     * $class = new \app\card\controller\Wxgetuserinfo();
     * $class->index();
     */

    /**
     * 1、获取用户信息
     */

    public function delsession(){
        session('userinfo', null);
        session(null);
    }

    public function index(){
        $appid = config('appid');
        $secret = config('secret');

        if(!session('?userinfo')){
            if (!isset($_GET['code'])){//没有code,去微信接口获取code码
                $request = request();
                $callback = $request->url(true);//微信服务器回调url,这里是本页url
//                $this->get_code($callback);
                $redirect_uri=urlencode($callback);
                $url='https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri='.$redirect_uri.'&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect';
                header("location:$url");exit();

            } else {//获取code后跳转回来到这里了
                $code = $_GET['code'];
                $data = $this->get_access_token($code);//获取网页授权access_token和用户openid
                $data_all = $this->get_user_info($data['access_token'],$data['openid']);//获取微信用户信息
                session('userinfo',$data_all);
                $this->checkuser($data_all['openid'],$data_all);
                return json($data_all);
            }
        }else{
            $ret=session('userinfo');
            return json($ret);             //返回的获取到的微信用户信息
        }
    }

    /**
     * 3、使用code换取access_token
     * @param string 用于换取access_token的code,微信提供
     * @return array access_token和用户openid数组
     */
    private function get_access_token($code){
        $appid = config('appid');
        $appsecret = config('secret');
        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $appid . '&secret=' . $appsecret . '&code=' . $code . '&grant_type=authorization_code';
        $user = json_decode(file_get_contents($url));
        if (isset($user->errcode)) {
            echo 'error:' . $user->errcode.'<hr>msg  :' . $user->errmsg;exit;
        }
        $data = json_decode(json_encode($user),true);//返回的json数组转换成array数组
        return $data;
    }

    /**
     * 4、使用access_token获取用户信息
     * @param string access_token
     * @param string 用户的openid
     * @return array 用户信息数组
     */
    private function get_user_info($access_token,$openid){
        $url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $access_token . '&openid=' . $openid . '&lang=zh_CN';
        $user = json_decode(file_get_contents($url));
        if (isset($user->errcode)) {
//            echo 'error:' . $user->errcode.'<hr>msg  :' . $user->errmsg;exit;
        }
        $data = json_decode(json_encode($user),true);//返回的json数组转换成array数组
        return $data;
    }

    /**
     * 检查用户信息
     * TODO 在这个地方如果在用户表加一个时间字段,就可以每隔多少次对数据库进行一次操作,而不是一直更新操作。
     */
    public function checkuser($openid,$data){
        $check=Db::name('wxuser')->where(array('openid'=>$openid))->find();
        if($check){
            /*更新用户信息*/
            $updata=array();
            $updata['avatar']=$data['headimgurl'];
            $updata['createtime']=time();
            $updata['nickname']=$data['nickname'];
            Db::name('wxuser')->where('openid',$openid)->update($updata);

            /*获取最新用户信息并存入缓存*/
            $newinfo=Db::name('wxuser')->where(array('id'=>$check['id']))->find();
            session('userinfo',$newinfo);

        }else{
            /*新增用户信息*/
            $intdata=array();
            $intdata = ['nickname' =>$data['nickname'], 'avatar' => $data['headimgurl'],'createtime'=>time(),'openid' => $data['openid'],'gender' => $data['sex'],'city' => $data['city'],'province' => $data['province'],'county' => $data['country']];
            Db::name('wxuser')->insert($intdata);
            $userId = Db::name('wxuser')->getLastInsID();
            /*获取最新用户信息并存入缓存*/
            if(!session('?userinfo')){
                $newinfo=Db::name('wxuser')->where(array('id'=>$userId))->find();
//                $newinfo=Db::name('wxuser')->where('id',$userId)->find();array('openid'=>$openid,'delstatus'=>1)
                session('userinfo',$newinfo);
            }
        }
    }


/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
    /*检测是否关注公众号*/
    /*subscribe    用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。*/
    /*https://www.cnblogs.com/mracale/p/9318349.html*/
    public function checkisgz(){
        $request = request();
        $callback = $request->url(true);//微信服务器回调url,这里是本页url

        $appid = config('appid');
        $secret = config('secret');

//微信网页授权获取openid
        $web_url=$callback;

        if (!isset($_GET['code'])) {
            $redirect_uri=urlencode($web_url);
            $url='https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri='.$redirect_uri.'&response_type=code&scope=snsapi_base&state=1#wechat_redirect';
            header("location:$url");exit();
        }
        $code=trim($_GET['code']);
        $url='https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$appid.'&secret='.$secret.'&code='.$code.'&grant_type=authorization_code';
        $access=file_get_contents($url);
        $data=json_decode($access,true);
        $access_token=$data['access_token'];
        $url='https://api.weixin.qq.com/sns/userinfo?access_token='.$access_token.'&openid=OPENID&lang=zh_CN';
        $user=file_get_contents($url);
        $arr=json_decode($user,true);
//获取用户的openid
        $openid=$arr['openid'];

        $url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret;
        $access=file_get_contents($url);
        $access_arr=json_decode($access,true);
//非网页的access_token
        $access_token=$access_arr['access_token'];

        $url="https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$access_token."&openid=".$openid."&lang=zh_CN";
        $res=file_get_contents($url);
//        var_dump($res);
        return $res['subscribe'];
    }




}

中间库:Basesdns.php

<?php
/**
 * Created by PhpStorm.
 * User: wudi
 * Date: 2019/1/28
 * Time: 14:37
 */

namespace app\card\controller;
use think\Controller;
use think\Db;
use think\Request;

class Basesdns extends Controller
{
    /**
     * 检测是否授权登录
     * 初始化方法,可以控制用户权限、获取菜单等等,只要是继承base类的其它业务类就不需要再重写
     */
    public function _initialize()
    {
        parent::_initialize();
        $class = new \app\card\controller\Wxgetuserinfo();
        $class->index();

        $userinfo=session('userinfo');
        if(!$userinfo){
            $class = new \app\card\controller\Wxgetuserinfo();
            $class->index();
        }


        $this->userinfo=session('userinfo');
    }
}

应用库,写日常逻辑的,需要继承中间库,个人认为前面所有的缓存只需要存一个openid就可以了。
Index.php

<?php
namespace app\card\controller;
use think\Db;
use think\Request;

class Index  extends Basesdns
{


    /*首页*/
    public function index()
    {
        $userinfo=session('userinfo');
        $userinfo=Db::name('wxuser')->where('openid',$userinfo['openid'])->find();
        session('userinfo',$userinfo);
        $this->assign('userinfo',$userinfo);
        return $this->fetch();
       
    }

}

config.php 用来配置 微信的appid跟secret。

2019-04-20T03:28:00.png

另外需要注意的是,公众号必须要加上对应服务器的ip白名单,以及网页授权回调域名配置。

这里再说一个很多人不知道的小消息,就是即使你没有服务号,也可以完成这个代码测试,只要你有一台服务器就可以了,没备案都没关系,那就是微信测试号。

注册微信测试号的地址是:
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

2019-04-20T03:33:02.png

推进观看的链接:http://www.cnblogs.com/hui9527/p/8473982.html 这个代码还不错。

阅读全文

微信关于网页授权access_token和普通access_token的区别

本文也是做一个笔记,根据自己的调用经历,再到网上查阅资料去验证,防止自己弄混淆。如果以后发现了新的异同,会在进行补充.

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183
调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功。小程序无需配置IP白名单。

一、两种access_token的获取:

网页授权access_token的获取:
https://blog.csdn.net/cl11992/article/details/86528704
全局access_token的获取:
https://blog.csdn.net/cl11992/article/details/86304653

二、官方解释
关于网页授权access_token和普通access_token的区别

微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;
其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。

三、自己相同点
同名
有效期:两者有效时间都是7200s。

四、自己不同点
网页授权access_token需要先获取code,才能才获取网页授权access_token;全局access_token可以直接调接口进行获取。
使用范围:通过网页授权获得的access_token,只能获取到对应的微信用户信息(授权作用域scope必须为snsapi_userinfo),与微信用户是一对一关系;而全局的access_token可以获取所有用户信息。
次数限制:网页授权的access_token获取次数没有限制;全局access_token每天获取最多次数为2000次(这个次数可以申请增加)。

阅读全文

微信H5授权登录获取用户信息

看完代码后,一定要注意末尾的两个注意事项,白名单跟网页授权域名的新增


<?php
/**
 * Created by PhpStorm.
 * User: 项羽
 * Date: 2019/1/28
 * Time: 10:31
 * QQ群:310325131
 */

namespace app\api\controller;


class Wxgetuserinfo
{
    /**
     * 1、获取用户信息
     */
    public function index(){
        $appid = config('appid');
        $secret = config('secret');
//        $fetch='/cc';
        /*TODO 检测是否关注公众号 直接调用 $this->checkisgz()*/
        $ret=array();

        if(!session('?userinfo')){
            if (!isset($_GET['code'])){//没有code,去微信接口获取code码
                $request = request();
                $callback = $request->url(true);//微信服务器回调url,这里是本页url
                /* $this->get_code($callback);*/
                /* 这个地方还是直接拿当前的方法走,不然部分手机调不起来授权登录。处理方法如下:*/
                $redirect_uri=urlencode($callback);
                $url='https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri='.$redirect_uri.'&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect';
                header("location:$url");exit();


            } else {//获取code后跳转回来到这里了
                $code = $_GET['code'];
                $data = $this->get_access_token($code);//获取网页授权access_token和用户openid
                $data_all = $this->get_user_info($data['access_token'],$data['openid']);//获取微信用户信息
                session('userinfo',$data_all);
                return json($data_all);
            }
        }else{
            $ret=session('userinfo');
            return json($ret);             //返回的获取到的微信用户信息
        }

        /*TODO 明信片二维码:B@     防伪码:C@   不参与兑换的明信片防伪码:A@ */
        /*$this->assign('retdata',$retdata);
        $this->assign('uniquecode',$uniquecode);
        $this->assign('userinfo',session('userinfo')['nickname']);
        return $this->fetch($fetch);*/
    }

    /**
     * 2、用户授权并获取code  这一步作废,上面直接调用
     * @param string $callback 微信服务器回调链接url
     */
    private function get_code($callback){
        $appid = config('appid');
        $scope = 'snsapi_userinfo';
        $state = md5(uniqid(rand(), TRUE));//唯一ID标识符绝对不会重复
        $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' . $appid . '&redirect_uri=' . urlencode($callback) .  '&response_type=code&scope=' . $scope . '&state=' . $state . '#wechat_redirect';
        header("Location:$url");
    }

    /**
     * 3、使用code换取access_token
     * @param string 用于换取access_token的code,微信提供
     * @return array access_token和用户openid数组
     */
    private function get_access_token($code){
        $appid = config('appid');
        $appsecret = config('secret');
        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $appid . '&secret=' . $appsecret . '&code=' . $code . '&grant_type=authorization_code';
        $user = json_decode(file_get_contents($url));
        if (isset($user->errcode)) {
            echo 'error:' . $user->errcode.'<hr>msg  :' . $user->errmsg;exit;
        }
        $data = json_decode(json_encode($user),true);//返回的json数组转换成array数组
//        error_log(time().'测试old'.print_r($data,true),3,dirname(__FILE__).'/error_log.php');
        return $data;
    }

    /**
     * 4、使用access_token获取用户信息
     * @param string access_token
     * @param string 用户的openid
     * @return array 用户信息数组
     */
    private function get_user_info($access_token,$openid){
        $url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $access_token . '&openid=' . $openid . '&lang=zh_CN';
        $user = json_decode(file_get_contents($url));
        if (isset($user->errcode)) {
//            echo 'error:' . $user->errcode.'<hr>msg  :' . $user->errmsg;exit;
        }
        $data = json_decode(json_encode($user),true);//返回的json数组转换成array数组

        return $data;
    }



/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
    /*检测是否关注公众号*/
    /*subscribe    用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。*/
    /*https://www.cnblogs.com/mracale/p/9318349.html*/
    public function checkisgz(){
        $request = request();
        $callback = $request->url(true);//微信服务器回调url,这里是本页url

        $appid = config('appid');
        $secret = config('secret');

//微信网页授权获取openid
        $web_url=$callback;

        if (!isset($_GET['code'])) {
            $redirect_uri=urlencode($web_url);
            $url='https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri='.$redirect_uri.'&response_type=code&scope=snsapi_base&state=1#wechat_redirect';
            header("location:$url");exit();
        }
        $code=trim($_GET['code']);
        $url='https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$appid.'&secret='.$secret.'&code='.$code.'&grant_type=authorization_code';
        $access=file_get_contents($url);
        $data=json_decode($access,true);
        $access_token=$data['access_token'];
        $url='https://api.weixin.qq.com/sns/userinfo?access_token='.$access_token.'&openid=OPENID&lang=zh_CN';
        $user=file_get_contents($url);
        $arr=json_decode($user,true);
//获取用户的openid
        $openid=$arr['openid'];

        $url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret;
        $access=file_get_contents($url);
        $access_arr=json_decode($access,true);
//非网页的access_token
        $access_token=$access_arr['access_token'];

        $url="https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$access_token."&openid=".$openid."&lang=zh_CN";
        $res=file_get_contents($url);
//        var_dump($res);
        return $res['subscribe'];
    }




}
注意事项如下所示
  1. 公众号白名单需要新增
  2. 网页授权回调地址需要添加

TIM截图20190128172733.png
2.png

阅读全文