【laravel+mysql+swoole商城项目-1】laravel微信授权登录

微信授权登录

一、构建项目

1 环境安装

2.框架安装

注意扩展的安装以及版本:

  • PHP >= 7.2.5
  • BCMath PHP 拓展
  • Ctype PHP 拓展
  • JSON PHP 拓展
  • Mbstring PHP 拓展
  • OpenSSL PHP 拓展
  • PDO PHP 拓展
  • Tokenizer PHP 拓展
  • XML PHP 拓展

Laravel 使用 Composer 来管理项目依赖。因此,在使用 Laravel 之前,请确保你的机器已经安装了 Composer。

//laravel安装命令

composer create-project --prefer-dist laravel/laravel blog "6.*"

代码可以打包通过ftp传输到虚拟机环境中。也可在本地进行测试开发,并不强制要求大家环境一致,但是版本请注意版本之前的兼容问题

3.虚拟机环境

虚拟机的环境建议可以直接安装宝塔:通过宝塔快速安装所需要的数据库以及PHP

在这里插入图片描述

需要安装的软件:

  1. mysql8.0
  2. redis
  3. Nginx
  4. php
  5. composer

3.1 前端环境安装

liunx安装node.js

Node.js 安装包及源码下载地址为:https://nodejs.org/en/download/

Node 官网已经把 linux 下载版本更改为已编译好的版本了,我们可以直接下载解压后使用

 wget https://nodejs.org/dist/v10.9.0/node-v10.9.0-linux-x64.tar.xz    // 下载
 tar xf  node-v10.9.0-linux-x64.tar.xz       // 解压
 cd node-v10.9.0-linux-x64/                  // 进入解压目录
./bin/node -v                               // 执行node命令 查看版本

v10.9.0
解压文件的 bin 目录底下包含了 node、npm 等命令,我们可以使用 ln 命令来设置软连接:

ln -s /usr/software/nodejs/bin/npm   /usr/local/bin/
ln -s /usr/software/nodejs/bin/node   /usr/local/bin/
windows安装node.js

下载网址:https://nodejs.org/zh-cn/download/

安装node.js详情

https://www.cnblogs.com/liuqiyun/p/8133904.html

composer环境安装

1、下载composer

[root@localhost ~]# curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading...

Composer (version 1.10.9) successfully installed to: /root/composer.phar
Use it: php composer.phar
[root@localhost ~]# mv composer.phar /usr/local/bin/composer
[root@localhost ~]# composer config -g repo.packagist composer https://packagist.phpcomposer.com

验证安装:
在这里插入图片描述

4. 授权登录流程

在这里插入图片描述

2.1 获取测试公众账号及其相关配置

微信公众平台开发者文档:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
微信公众号测试号获取地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

5.公众测试账号获取

访问上面的链接,通过微信客户端扫码登录即可登录。登录完即可获取到一个测试公众账号的信息。主要有appId和appsecret两个参数,这将唯一标示一个公众号,并且需要将他们作为参数获取用户的信息。
在这里插入图片描述
关注公众号

用户只有关注了这个公众号了,才能通过打开有公众号信息的链接去授权第三方登录,并获取用户信息的操作。故我们还需要用我们的微信关注微信号,操作如下: 还是刚刚那个登录成功后跳转的页面,我们可以看到,该页面有一个二维码,我们可以通过扫描该二维码进行关注,关注成功在右边的“用户列表”会多一个用户的信息。如下图所示:
在这里插入图片描述
配置回调函数
在这里插入图片描述

我们在微信客户端访问第三方网页(即我们自己的网页)的时候,我们可以通过微信网页授权机制,我们不仅要有前面获取到的appid和appsecret还需要有当用户授权之后,回调的域名设置,即用户授权后,页面会跳转到哪里。具体的配置如下: 还是在刚刚的页面,有一个“网页授权获取用户基本信息”,点击后面的修改

在这里插入图片描述

二、 实现微信授权登录

网页授权:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
具体而言,网页授权流程分为四步:

1、引导用户进入授权页面同意授权,获取code

参数:
在这里插入图片描述通过PHP artisan 命令创建微信授权登录控制器

php artisan make:controller WeChateController

// WeChateController

<?php
public function wxcode()
{
  //微信授权登录相关信息
  $params = http_build_query([
  'appid' => 'wx849ea16e0f42f232', //微信公众平台提供的appid
  'redirect_uri' => 'http://blog-shop.com/wxtoken', //你想要回调的地址
  'response_type' => 'code',
  'scope' => 'snsapi_userinfo',
]);
  //第一步:用户同意授权,获取code
  $url  = 'https://open.weixin.qq.com/connect/oauth2/authorize?' . $params . '#wechat_redirect';//获取用户code接口
  return redirect($url);
}
?>

注意:
1.手册第一个参数
在这里插入图片描述2.
在这里插入图片描述3.访问

Route::get('wxCode','WeChateController@wxcode');

2、通过code换取网页授权access_token(与基础支持中的access_token不同)

<?php
public function wxtoken(Request $resquest)
{
  #根据拿到的code值去访问用户的access_token令牌
  $params = http_build_query([
          'appid' => 'wx849ea16e0f42f232',
          'secret' => '0864a3720d5972c8bbb49e029cbd033f',
          'code' => $resquest->input('code'),
          'grant_type' => 'authorization_code'
  ]);
  $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?' . $params;
  $result = file_get_contents($url);
  $access_token = json_decode($result);
  dd($access_token);
}
 ?>

3、刷新网页授权access_token,避免过期(这里只需要根据上面的接口一样进行数据获取即可)

4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

<?php
public function wxtoken(Request $resquest)
{
  #根据拿到的code值去访问用户的access_token令牌
  $params = http_build_query([
          'appid' => 'wx849ea16e0f42f232',
          'secret' => '0864a3720d5972c8bbb49e029cbd033f',
          'code' => $resquest->input('code'),
          'grant_type' => 'authorization_code'
  ]);
  $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?' . $params;
  $result = file_get_contents($url);
  $access_token = json_decode($result);

  $params = http_build_query([
    'access_token' => $access_token->access_token,
    'openid' => $access_token->openid,
    'lang' => 'zh_CN'
  ]);

  $url = "https://api.weixin.qq.com/sns/userinfo?".$params;
  $UserInfo = json_decode(file_get_contents($url));
  dd($UserInfo);
}
?>

根据路由访问:

Route::get('wxcode','WeChateController@wxcode');
Route::get('wxtoken','WeChateController@wxtoken');

在这里插入图片描述

三 、运用esaywechat配合中间件实现

第一步:去微信公众号中设置和获取信息

注意:公众号必须已经认证,且必须拥有网页授权获取用户基本信息的权限。

开发-基本配置-公众号开发信息,获取 app_id 和 app_secret 这两个参数。
开发-基本配置-公众号开发信息,IP白名单中设置你的服务器公网IP。
设置-公众号设置-功能设置,业务域名中添加你的域名(主要用于防止微信中访问网页时进行转码和风险提示)。
设置-公众号设置-功能设置,网页授权域名中添加你的域名。

第二步:安装 EasyWeChat 的 Laravel 拓展包

EasyWeChat 的 Laravel 拓展包:https://packagist.org/packages/overtrue/laravel-wechat
EasyWeChat是一个开源的微信非官方SDK。EasyWeChat 的安装非常简单,因为它是一个标准的 Composer 包,这意味着任何满足下列安装条件的 PHP 项目支持 Composer 都可以使用它

PHP >= 7.0
PHP cURL 扩展
PHP OpenSSL 扩展
PHP SimpleXML 扩展
PHP fileinfo 拓展

安装前请切换到项目的根目录下。

composer require "overtrue/laravel-wechat:~5.0"

注意:安装完成后 Laravel 默认已经把 EasyWeChat 做为服务嵌入到了框架中,所以在开发中使用的代码和 EasyWeChat 官方帮助文档中稍微有不同,当然如果你不使用 Laravel 的服务特性或是原生方式,可以直接按官网的来,更具体可以查看 EasyWeChat 和 EasyWeChat Laravel 5 拓展包的使用文档。

第三步创建配置文件

php artisan vendor:publish --provider="Overtrue\LaravelWeChat\ServiceProvider"

这里使用的是微信中登陆功能,因此需要将 app_id 和 secret 修改为你的公众号参数,其他默认就好,可以在 /config/wechat.php 中修改,或者也可以在 .evn 中添加并赋值,两个方式选其一,具体区别请阅读官方文档。

在 /config/wechat.php 中的 official_account 节点中修改:

/*
 * 公众号
 */
'official_account' => [
    'default' => [
        'app_id' => env('WECHAT_OFFICIAL_ACCOUNT_APPID', 'your-appid'),         // AppID
        'secret' => env('WECHAT_OFFICIAL_ACCOUNT_SECRET', 'your-secret'),    // AppSecret
        'token' => env('WECHAT_OFFICIAL_ACCOUNT_TOKEN', ''),           // Token
        'aes_key' => env('WECHAT_OFFICIAL_ACCOUNT_AES_KEY', ''),                 // EncodingAESKey

        /*
         * OAuth 配置
         *
         * scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login
         * callback:OAuth授权完成后的回调页地址(如果使用中间件,则随便填写。。。)
         */
        'oauth' => [
            'scopes'   => array_map('trim', explode(',', env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_SCOPES', 'snsapi_userinfo'))),
            'callback' => env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_CALLBACK', '/products'),
        ],
    ],
],

第四步:在.evn中添加并赋值

WECHAT_OFFICIAL_ACCOUNT_APPID = your-app-id
WECHAT_OFFICIAL_ACCOUNT_SECRET = your-app-secret

第五步:注册中间件

/app/Http/Kernel.php 中的 protected $routeMiddleware 节点添加

'Auth.WeChat' => \Overtrue\LaravelWeChat\Middleware\OAuthAuthenticate::class,

/config/app.php 中的 providers与 节点中添加

'providers' => [
  ...
  \Overtrue\LaravelWeChat\ServiceProvider::class,
]

'aliases' => [
  ...
  'EasyWeChat' => \Overtrue\LaravelWeChat\Facade::class,
]

第六步:创建测试路由,添加中间件

在路由文件web.php中添加:

Route::get('wechat/auth', function(){
    $wechat = session('wechat.oauth_user.default'); //拿到授权用户资料
    dd($wechat); //打印出授权用户资料
})->middleware('Auth.WeChat');

此时,打开微信,在微信中访 http://你的域名/wechat/auth 试试,点击同意授权后,就会打印出你当前微信的用户资料。

如果在本地安装组件上传并配置之后 ,这里还会出现找不到服务的情况,请参考https://blog.csdn.net/qq_38941567/article/details/107907855

注意:必须在微信中访问,因为在浏览器中访问是需要微信开放平台的接口

这里可能会出现error
在这里插入图片描述

这个错误是因为我们并没授权登录,在esaywechat拉取授权登录信息的时候重定向头信息验证出现异常。

解决:可以通过修改中间件代码去解决问题

修改 \Overtrue\LaravelWeChat\Middleware\OAuthAuthenticate 中的handle方法代码,如下:

<?php
session([$sessionKey => $officialAccount->oauth->userFromCode($request->get('code')) ?? []]);
修改为:
session([$sessionKey => $officialAccount->oauth->user() ?? []]);

return redirect()->to($officialAccount->oauth->scopes($scope)->redirect($request->fullUrl()));
修改为:
return r$officialAccount->oauth->scopes($scope)->redirect($request->fullUrl())?>

修改好了之后访问:

在这里插入图片描述

第七步:完善编写授权代码

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use App\Models\User;
use EasyWeChat\Factory;

class WeChatController extends Controller
{
    //微信授权登录代码
    public function auth(Request $request)
    {
      //通过session获取用户授权信息
      $Auth = session('wechat.oauth_user.default');

      //查询并判断微信用户是否已在并平台进行注册
      $user = User::where('openid',$Auth['id'])->first();
        //用户的密码需要他在第一次登录的时候进行设置
        //手机号码需要进行绑定,需要根据用户id来进行异构索引表分表
      if (!$user) {
        // code...
        $result = User::create([
          		'id' => $this->uuid(),
             'Openid' => $Auth['id'],
             'username' => $Auth['name'],
             'role_id' => 1,//角色默认1位普通用户
             'vender_type' => 2,
             'status' => 0,
             'login_ip' => $request->getClientIp()

        ]);
      }else {
        $result = $user;
      }
      //注册或者是验证完毕之后进行登录
      Auth::login($result,true);
      //重定向到商城首页地址
      return redirect('/products');
    }
    public function uuid($prefix='')
    {
        $str = md5(uniqid(mt_rand(), true));
        $uuid  = substr($str,0,8) . '-';
        $uuid .= substr($str,8,4) . '-';
        $uuid .= substr($str,12,4) . '-';
        $uuid .= substr($str,16,4) . '-';
        $uuid .= substr($str,20,12);
        return $prefix . $uuid;

    }
}
?>

//app/User.php

    protected $fillable = [
        'id','username', 'Openid','password','role_id','vender_type',
        'status','mobile','login_ip'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

第八步:创建正式路由,添加中间件

此时可以注释或者删除掉刚才创建的路由信息,并添加正式的路由:

//esaywechat配合中间件登录

Route::get('WeChat','WeChatController@auth')->middleware('Auth.WeChat')->name('Login.WeChat');

第九步:创建商品首页控制器

通过PHP artisan 命令创建商品首页控制器

php artisan make:controller ProductController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ProductController extends Controller
{
    //

    public function index()
    {

        return '商品首页';

    }
}

四、信公众号菜单处理

自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能。开启自定义菜单后,公众号界面如图所示:
在这里插入图片描述

请注意: 自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。
一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“…”代替。
创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。
​ 自定义菜单接口可实现多种类型按钮,如下:

菜单类型名称菜单类型描述
click点击推事件用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互
view跳转URL用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息
scancode_push扫码推事件用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后显示扫描结果(如果是URL,将进入URL),且会将扫码的结果传给开发者,开发者可以下发消息
scancode_waitmsg扫码推事件且弹出“消息接收中”提示框用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具,然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息
pic_sysphoto弹出系统拍照发图用户点击按钮后,微信客户端将调起系统相机,完成拍照操作后,会将拍摄的相片发送给开发者,并推送事件给开发者,同时收起系统相机,随后可能会收到开发者下发的消息
pic_photo_or_album弹出拍照或者相册发图用户点击按钮后,微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程
pic_weixin弹出微信相册发图器用户点击按钮后,微信客户端将调起微信相册,完成选择操作后,将选择的相片发送给开发者的服务器,并推送事件给开发者,同时收起相册,随后可能会收到开发者下发的消息
location_select弹出地理位置选择器用户点击按钮后,微信客户端将调起地理位置选择工具,完成选择操作后,将选择的地理位置发送给开发者的服务器,同时收起位置选择工具,随后可能会收到开发者下发的消息
media_id下发消息(除文本消息)用户点击media_id类型按钮后,微信服务器会将开发者填写的永久素材id对应的素材下发给用户,永久素材类型可以是图片、音频、视频、图文消息。请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id
view_limited跳转图文消息URL用户点击view_limited类型按钮后,微信客户端将打开开发者在按钮中填写的永久素材id对应的图文消息URL,永久素材类型只支持图文消息。请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id

请注意,3到8的所有事件,仅支持微信iPhone5.4.1以上版本,和Android5.4以上版本的微信用户,旧版本微信用户点击后将没有回应,开发者也不能正常接收到事件推送。9和10,是专门给第三方平台旗下未微信认证(具体而言,是资质认证未通过)的订阅号准备的事件类型,它们是没有事件推送的,能力相对受限,其他类型的公众号不必使用。

{
    "button": [
        {
            "type": "view",
            "name": "进入商城",
            "url": "http://lms-shops.com/WeChat"
        },
        {
            "name": "菜单",
            "sub_button": [
                {
                    "type": "view",
                    "name": "我的订单",
                    "url": "http://lms-shops.com/order"
                },
                {
                    "type": "view",
                    "name": "购物车",
                    "url": "http://lms-shops.com/cart"
                },
                {
                    "type": "view",
                    "name": "个人中心",
                    "url": "http://lms-shops.com/member"
                }
            ]
        }
    ]
}

对于不同参数类型可以参考:https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.html

设置成功之后哦,在微信中可以查看自定义好的微信公众号菜单:
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现这个功能需要用到两个接口,一个是根据经纬度查询城市的接口,另一个是根据城市名查询经纬度的接口。 首先,我们需要获取用户的经纬度信息。可以使用浏览器的 Geolocation API 或者通过 IP 地址查询服务来获取。获取到经纬度后,可以调用根据经纬度查询城市的接口。 以下是使用 Laravel+Swoole 实现的代码示例: ```php use Swoole\Coroutine\Http\Client; function getCityByLatLng($lat, $lng) { // 调用根据经纬度查询城市的接口 $client = new Client('api.map.baidu.com', 443, true); $client->set(['timeout' => 10]); $client->get('/geocoder/v2/', [ 'location' => "$lat,$lng", 'output' => 'json', 'ak' => 'your_ak', // 填写你的百度地图开发者密钥 ]); $response = json_decode($client->body, true); if ($response['status'] == 0) { return $response['result']['addressComponent']['city']; } return null; } function getLatLngByCity($city) { // 调用根据城市名查询经纬度的接口 $client = new Client('api.map.baidu.com', 443, true); $client->set(['timeout' => 10]); $client->get('/geocoder/v2/', [ 'address' => $city, 'output' => 'json', 'ak' => 'your_ak', // 填写你的百度地图开发者密钥 ]); $response = json_decode($client->body, true); if ($response['status'] == 0) { $location = $response['result']['location']; return [$location['lat'], $location['lng']]; } return null; } // 示例:根据经纬度返回对应城市 $lat = 39.915168; $lng = 116.403875; $city = getCityByLatLng($lat, $lng); echo $city; // 北京市 // 示例:根据城市返回对应经纬度 $city = '北京市'; $latLng = getLatLngByCity($city); print_r($latLng); // Array ( [0] => 39.90469 [1] => 116.40717 ) ``` 另外,如果你需要根据城市查询经纬度的功能,推荐使用第三方库如 `geocoder-php` 或 `googlemaps/google-maps-services-php`,这些库已经封装好了各种地图服务的 API,使用起来更加方便。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值