整合ThinkPHP功能系列之微信网页OAuth2.0授权登录

OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用

越来越多的平台支持用户使用微信进行授权第三方登录,在顺应这个联合登录的趋势的同时,也有越来越多的平台选择使用微信的授权登录

今天就来说一下微信授权登陆的操作,微信授权登录有两种,一是点击授权登陆,二是静默授权,但是两者的权利不一样,能获取到的数据也是不一样的

点击授权登录

需要登录时,页面跳转到授权页面,也就是我们经常看到的绿色授权页面,用户授权后可从微信拿到openid、unionid

静默授权

静默授权下,不需要跳转页面让用户确认授权,而是直接授权用户登录,但是静默授权只能拿到用户的openid和unionid,无法拿到用户的微信头像、微信名称等个人信息

我们这里主要模拟在微信公众号中使用OAuth2.0进行授权,获取用户的基本信息的过程。详细的开发文档可查看微信的官方文档

微信授权使用的是OAuth2.0授权的方式,主要有以下简略步骤:

第一步:用户同意授权,获取code

第二步:通过code换取网页授权access_token

第三步:刷新access_token(如果需要)

第四步:拉取用户信息(需scope为 snsapi_userinfo)

下面是具体操作

首先判断用户是否登陆过,没有登录开始申请授权

public function _initialize(){
    // 验证用户是否登录
    $userId = S('userId');
    if(!$userId){
        //获取当前网页,授权后返回
        $callBackUrl = urlencode(__SELF__);

        // 微信用户
        $wechat = C('WECHAT');
        $appid = $wechat['appid'];
        $redirect_uri = urlencode ('http://'.$_SERVER['HTTP_HOST'].'/Login/authCallback?mid='.S('mid').'&CallbackUrl='.$callBackUrl);
        $url ="https://open.weixin.qq.com/connect/oauth2/authorize?appid={$appid}&redirect_uri={$redirect_uri}&response_type=code&scope=snsapi_userinfo&state=1&connect_redirect=1#wechat_redirect";
        header("Location:".$url);
        exit(0);
    }
}

用户授权跳转到回调网址后,我们根据获取到code换取网页授权access_token

public function authCallback($code)
{
    $wechat = C('WECHAT');
    $appid = $wechat['appid'];
    $secret = $wechat['appKey'];

    // 获取用户授权信息
    $authInfo = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$secret}&code={$code}&grant_type=authorization_code";
    $authInfo = $this->getJson($authInfo);

    //第二步:根据全局access_token和openid查询用户信息
    $access_token = $authInfo["access_token"];
    $openid = $authInfo['openid'];
    if(!$openid){
        $this->error('授权失败,稍后请重试!');
    }

    // 根据用户openid查看用户是否存在
    $user = M('User')->where("wx_openid = '%s '",$openid);

    // 存在则直接登录
    if($user){
        $callBackUrl = urldecode(I('get.CallbackUrl'));
        S('userId', $user['id']);
        header("Location:".'http://'.$_SERVER['HTTP_HOST'].$callBackUrl);
        exit(0);
    }

    // 存储openid 进行注册
    S('wx_openid', $openid);
    // ...省略

    // 获取用户微信信息
    $getWxInfourl = "https://api.weixin.qq.com/sns/userinfo?access_token={$access_token}&openid={$openid}&lang=zh_CN";
    $wxUserInfo = $this->getJson($getWxInfourl);
    S('userInfo', $wxUserInfo);
    header('Location:'.U('/login/login'));
    exit(0);
}

获取网页授权access_token和openid后拉取用户信息,保存在数据库中,完成业务逻辑即可

拉取用户信息的时候,请求的链接返回的是如下json数据

{
    "openid":" OPENID",
    " nickname": NICKNAME,
    "sex":"1",
    "province":"PROVINCE",
    "city":"CITY",
    "country":"COUNTRY",
    "headimgurl": "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
    "privilege":[ "PRIVILEGE1" "PRIVILEGE2"],
    "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

所以我们封装一个curl去请求该链接

protected function getJson($url){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);

    return json_decode($output, true);
}

好了,收工,如果有错误的话查看一下对应的错误码

沈唁志|一个PHPer的成长之路! 原创文章采用CC BY-NC-SA 4.0协议进行许可,转载请注明:转载自:整合ThinkPHP功能系列之微信网页OAuth2.0授权登录

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏CodeSheep的技术分享

Elastic Search搜索引擎在SpringBoot中的实践

21750
来自专栏大数据文摘

硬盘数据恢复的神器有哪些?

293150
来自专栏从流域到海域

《笨办法学Python》 第46课手记

《笨办法学Python》 第46课手记 这节课制作了一个Python的项目骨架,花了我一个晚上和一个早上的时间,原因是我下载的pdf里面只有OX S的命令行,而...

24960
来自专栏蔡鹏的专栏

开源分布式监控系统 OWLv5.0.0 安装部署完整手册

OWL 是TalkingData公司推出的一款开源分布式监控系统 . 目前使用OWL监控了二十几台服务器,便捷很多 Go语言开发,部署维护简单

57980
来自专栏北京马哥教育

使用monit搭建一个监控系统

马哥linux运维 | 最专业的linux培训机构 ---- 上周用monit搭建或者说定制了一个监控系统,来监控服务器发生事情。当然了主要是监控异常,因为我...

44070
来自专栏惨绿少年

Zabbix 3.0 从入门到精通(zabbix使用详解)

第1章 zabbix监控 1.1 为什么要监控      在需要的时刻,提前提醒我们服务器出问题了      当出问题之后,可以找到问题的根源      网站/...

1.1K10
来自专栏zhisheng

《从0到1学习Flink》—— Flink 配置文件详解

前面文章我们已经知道 Flink 是什么东西了,安装好 Flink 后,我们再来看下安装路径下的配置文件吧。

38200
来自专栏FreeBuf

西部数据NAS设备被曝存在硬编码后门和未授权文件上传高危漏洞

近日,GulfTech公司安全研究员James Bercegay发现,西部数据(Western Digital)旗下多个MyCloud系列网络存储设备(WDMy...

34250
来自专栏架构师之路

DB主从一致性架构优化4种方法

需求缘起 大部分互联网的业务都是“读多写少”的场景,数据库层面,读性能往往成为瓶颈。如下图:业界通常采用“一主多从,读写分离,冗余多个读库”的数据库架构来提升数...

43760
来自专栏java一日一条

数据库的读写分离

读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务...

18130

扫码关注云+社区

领取腾讯云代金券