Laravel 集成微信用户登录和绑定的实现


Posted in PHP onDecember 27, 2019

最近主要在忙活微信与支付宝平台的对接与开发,本篇就基于后端层面来讲述一下微信的登录与绑定实现。

(一)申请微信开放平台

最首先的话就是需要去微信开发中心https://open.weixin.qq.com,创建一个账号,然后创建自己的移动或网站应用。

Laravel 集成微信用户登录和绑定的实现

创建完成后,就会需要腾讯的审核,整个过程在1-3天,基本上1天左右就能完成,审核通过如下图所示。

Laravel 集成微信用户登录和绑定的实现

(二) 、封装微信相关接口

微信移动应用开发文档:https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Login/Authorized_API_call_UnionID.html

审核通过后,就需要来封装微信授权、可信息获取的接口。

封装微信授权 && 用户信息获取

微信授权接口:https://api.weixin.qq.com/sns/oauth2

需要填写的参数如下:

参数 是否必须 说明
appid 应用唯一标识,在微信开放平台提交应用审核通过后获得
secret 应用密钥 AppSecret,在微信开放平台提交应用审核通过后获得
code 填写第一步获取的 code 参数
grant_type 填 authorization_code

下面通过我们的PHP代码实现:

<?php
namespace App\Helpers;

use GuzzleHttp\Client;
use Illuminate\Support\Arr;

class WechatAppUtils
{
  protected $client = null;

  protected $config = [];

  public function __construct()
  {
    $this->config = [
      'wechat_app' => [
        'appid' => env('WECHAT_APPID'),  //审核通过的APPID
        'secret' => env('WECHAT_SECRET'),  //应用APP SECRET 详情见上图
      ],
      'time_out'  => 5,
    ];
    $this->client = new Client([
      'time_out' => $this->config['time_out'],
    ]);
  }

  /**
   * 获取微信用户access_token
   *
   * @param [String] $code
   * @return Array
   */
  public function accessToken($code)
  {
    $accessTokenUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token';

    $response = $this->client->request('GET', $accessTokenUrl, [
      'query' => [
        'grant_type' => 'authorization_code',
        'code'    => $code,
        'appid'   => Arr::get($this->config, 'wechat_app.appid'),
        'secret'   => Arr::get($this->config, 'wechat_app.secret'),
      ],
    ]);

    $result = $response->getbody()->getContents();

    return empty($result) ? null : json_decode($result, true);
  }

  /**
   * 微信用户信息
   *
   * @param [String] $accessToken
   * @param [String] $openId
   * @return Array
   */
  public function userInfo($accessToken, $openId)
  {
    $userInfoUrl = 'https://api.weixin.qq.com/sns/userinfo';

    $response = $this->client->request('GET', $userInfoUrl, [
      'query' => [
        'access_token' => $accessToken,
        'openid'    => $openId,
        'lang'     => 'zh_CN',
      ],
    ]);

    $result = $response->getbody()->getContents();

    return empty($result) ? null : json_decode($result, true);
  }
}

上面的accessToken方法主要是实现用户授权,效验的code参数是客户端传递过来的,当成功获取收钱用户的授权信息后,可以根据用户的OPENID来调用userInfo方法查询相关用户的信息,包含了用户的昵称、头像、性别等等。

具体客户端开发文档可以参考这篇:https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Login/Development_Guide.html。

上面的用到的Http Client是一个第三方拓展包,叫做GuzzleHttp,是一个PHP HTTP客户端,可以轻松发送HTTP请求,并且可以轻松集成Web服务。

我们可以通过composer一键安装:

composer require guzzlehttp/guzzle

(三)、完善用户微信授权登录

完成上述的封装操作后,我们便开始讲微信接入到我们自己的系统中与用户进行关联起来,下面是微信接入的一张时序图。

Laravel 集成微信用户登录和绑定的实现

如果用户想使用微信登录,首先会通过客户端唤起微信,请求登录第三方应用,然后微信会询问用户是否成功授权给XX应用,授权成功后,客户端会得到一个授权码:code,然后客户端携带code请求我们的客户端API,进行授权绑定,授权成功后,会得到授权用户OPENID(应用下的唯一标识),反之抛出异常信息提示用户。

建立OAuth表,用于储存用户的授权信息。

建立一张o_auths table 储存用户的授权信息,设计oauth_type字段使其成为一个多态模型,方便接入以后的微博、支付宝、QQ接入等等。

Schema::create('o_auths', function (Blueprint $table) {
  $table->increments('id');
  $table->unsignedInteger('user_id')->index()->comment('用户ID');
  $table->morphs('o_auth');
  $table->json('data')->nullable()->comment('授权信息');
  $table->timestamps();
});

完善用户授权绑定

建立好o_auths table,下面开始完善用户授权绑定的逻辑:

function wechat(User $user, $code)
{
  $utils = new WechatAppUtils;

  //获取微信token
  $accessTokens = $utils->accessToken($code);
  throw_if(!Arr::has($accessTokens, ['unionid', 'openid']), Exception::class, '授权失败,请稍后再试!');

  //建立oauth关联
  $oAuth = OAuth::firstOrNew(['oauth_type' => 'wechat', 'oauth_id' => $accessTokens['openid']]);
  throw_if(isset($oAuth->id),Exception::class,'该微信已绑定,请直接登录!');
  $oAuth->user_id = $user->id;
  $oAuth->data  = Arr::only($accessTokens, ['openid', 'refresh_token']);
  $oAuth->save();

  return $oAuth;
}

首先会通过客户端传递过来的Code获取当前用户授权,然后查询该用户是否已授权过,已授权过就提醒用户直接去登录,否则绑定授权信息,返回给客户端。

完善微信登录

完善好用户授权后,登录就显得非常容易了,只需要简单查询授权记录,存在则返回对应绑定的用户,否则抛出异常信息提示用户。

public function signIn($user, $code)
{
  $utils = new WechatAppUtils;
  //获取微信token
  $accessTokens = $utils->accessToken($code);
  throw_if(!Arr::has($accessTokens, ['unionid', 'openid']), Exception::class, '授权失败,请稍后再试!');
  $oauth = $this->getUserOauth($user, 'wechat');
  throw_if(is_null($oauth), UserException::class, '授权失败,该账户未绑定!');

  return $oauth;
}

public function getUserOauth(User $user, $oAuthType)
{
  return OAuth::where(['oauth_type' => $oAuthType, 'user_id' => $user->id])->first();
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
php下使用iconv需要注意的问题
Nov 20 PHP
PHP中改变图片的尺寸大小的代码
Jul 17 PHP
PHP通过iconv将字符串从GBK转换为UTF8字符集
Jul 18 PHP
深入PHP中慎用双等于(==)的详解
Jun 06 PHP
关于PHP模板Smarty的初级使用方法以及心得分享
Jun 21 PHP
浅析Mysql 数据回滚错误的解决方法
Aug 05 PHP
php中多维数组按指定value排序的实现代码
Aug 19 PHP
php遍历类中包含的所有元素的方法
May 12 PHP
Smarty使用自定义资源的方法
Aug 08 PHP
PHP自定义函数获取URL中一级域名的方法
Aug 23 PHP
php实现有序数组打印或排序的方法【附Python、C及Go语言实现代码】
Nov 10 PHP
php基于数组函数实现关联表的编辑操作示例
Jul 04 PHP
PHP单元测试配置与使用方法详解
Dec 27 #PHP
PHP全局使用Laravel辅助函数dd
Dec 26 #PHP
解决php用mysql方式连接数据库出现Deprecated报错问题
Dec 25 #PHP
PHP高并发和大流量解决方案整理
Dec 24 #PHP
thinkphp5实现微信扫码支付
Dec 23 #PHP
PHP实现笛卡尔积算法的实例讲解
Dec 22 #PHP
PHP架构及原理知识点详解
Dec 22 #PHP
You might like
PHP获取当前日期所在星期(月份)的开始日期与结束日期(实现代码)
2013/06/18 PHP
解析二进制流接口应用实例 pack、unpack、ord 函数使用方法
2013/06/18 PHP
安装apache2.2.22配置php5.4(具体操作步骤)
2013/06/26 PHP
javascript 特性检测并非浏览器检测
2010/01/15 Javascript
js克隆对象、数组的常用方法介绍
2013/09/26 Javascript
JavaScript实现的多个图片广告交替显示效果代码
2015/09/04 Javascript
全面解析标签页的切换方式
2016/08/21 Javascript
JS中append字符串包含onclick无效传递参数失败的解决方案
2016/12/26 Javascript
JavaScript代码判断输入的字符串是否含有特殊字符和表情代码实例
2017/08/17 Javascript
Vue三层嵌套路由的示例代码
2018/05/05 Javascript
vue实现购物车的小练习
2020/12/21 Vue.js
[02:08]我的刀塔不可能这么可爱 胡晓桃_1
2014/06/20 DOTA
pyqt4教程之messagebox使用示例分享
2014/03/07 Python
Python 中的 else详解
2016/04/23 Python
Python正则表达式分组概念与用法详解
2017/06/24 Python
目前最全的python的就业方向
2018/06/05 Python
python 多线程将大文件分开下载后在合并的实例
2018/11/09 Python
美国著名的团购网站:Woot
2016/08/02 全球购物
美国著名的家居用品购物网站:Bed Bath & Beyond
2018/01/05 全球购物
Senreve官网:美国旧金山的奢侈手袋品牌
2019/03/21 全球购物
Kathmandu美国网站:新西兰户外运动品牌
2019/03/23 全球购物
Sarenza德国:法国最大的时尚鞋和包包网上商店
2019/06/08 全球购物
MVC的各个部分都有那些技术来实现?如何实现?
2016/04/21 面试题
体现团队精神的口号
2014/06/06 职场文书
文艺演出策划方案
2014/06/07 职场文书
超市客服工作职责
2014/06/11 职场文书
视光学专业自荐信
2014/06/24 职场文书
白酒营销策划方案
2014/08/17 职场文书
中国在我心中演讲稿
2014/09/13 职场文书
渠道运营商合作协议书范本
2014/10/06 职场文书
公司与个人合作协议书
2016/03/19 职场文书
哪类餐饮行业,最适合在高校创业?
2019/08/19 职场文书
JPA如何使用entityManager执行SQL并指定返回类型
2021/06/15 Java/Android
elementui的el-popover修改样式不生效的解决
2021/06/30 Javascript
oracle数据库去除重复数据
2022/05/20 Oracle
vue/cli 配置动态代理无需重启服务的方法
2022/05/20 Vue.js