当前位置:首页 > PHP > 正文内容

laravel实现微信公众号授权登录实战

陈杰1年前 (2020-12-31)PHP1618

微信公众号授权登录实战


框架:laravel

依赖:overtrue/wechat


首先安装一下easywechat依赖

composer require overtrue/wechat:~4.0 -vvv

安装完成后我们定义一个makeWechat方法

public static function makeWechat()
{
   $config = [
       'app_id'        => env('WECHAT_APPID'),
       'secret'        => env('WECHAT_APPSECRET'),
       'response_type' => 'array',
   ];

   $app = Factory::officialAccount($config);
   return $app;
}

我们return的$app后面要用到的地方很多,所以直接定义一个基础方法吧


写一个中间件,该中间件管理所有需要登录才能操作的接口


<?php

namespace App\Http\Middleware;
use App\Libraries\AdminSend;
use App\Model\UserModel;
use Closure;

class CheckLogin
{
   use AdminSend;

   public function handle($request, Closure $next)
   {
       $url = $request->fullUrl();
       try {
           $key    = env("TOKEN_KEY");
           $header = $request->cookie('authorization');

           $authorizationInfo =
               explode(":", openssl_decrypt(base64_decode($header), 'DES-EDE3', $key, OPENSSL_RAW_DATA));
           if (!is_array($authorizationInfo) || $authorizationInfo[0] < 1)
               return self::returnLogin($url);

           $user = UserModel::get_by_id((int)$authorizationInfo[0]);

           if ($user and !isset($user) || $user['token'] != $authorizationInfo[1])
               return self::returnLogin($url);

           $request->attributes->add(['uid' => $authorizationInfo[0], 'user' => $user]);

           return $next($request);
       } catch (\Exception $e) {
           return self::returnLogin($url);
       }
   }
}


主要逻辑是取request的cookie值,通过cookie值来判断用户是否登录了。

如果没有登录就returnLogin,该方法有一个参数为url,目的是为了跳转到微信公众号登录且登录成功后还继续跳回到之前用户想要访问的页面


看看returnLogin方法

public static function returnLogin($url)
{
   Session::flash("redirect_url", $url);
   $app   = self::makeWechat();
   $oauth = $app->oauth;
   return $oauth->scopes(['snsapi_userinfo'])->redirect(url("/user/login"));
}

首先用了一个Session::falsh方法,这里就是通过seesion来缓存当前用户的来源地址,也就是为了上面提到了登录成功后继续跳转到登录之前的来路页面


然后跳转到user/login方法

来看看我们的login方法

public function login(Request $request)
{
   $app         = self::makeWechat();
   $oauth       = $app->oauth;
   $user_wechat = $oauth->user()->toArray();
   $user        = UserModel::query()->where('openid', $user_wechat['id'])->first();
   if (!isset($user)) {
       $user              = new UserModel();
       $user->name        = $user_wechat['name'];
       $user->openid      = $user_wechat['id'];
       $user->token       = $user_wechat['token'];
       $user->avatar      = $user_wechat['avatar'];
       $user->sex         = $user_wechat['original']['sex'];
       $user->provider    = "wechat";
       $user->create_time = time();
       $user->save();
   }
   $token = self::TokenEncrypt($user['id'], $user['token'], env("TOKEN_KEY"));
   $url   = Session::get("redirect_url");
   return response()->redirectTo($url)->withCookie(cookie('authorization', $token));
}


用户通过微信公众号授权后就会访问该方法,该方法拿到用户的openid去比对我们的数据库是否存在会员,如果存在就是登录,如果不存在那么就需要为该用户注册账号。

登录成功后返回登录cookie并且跳转到来路页面。


这里有一个TokenEncrypt的方法,其实就是生成我们的cookie一并分享出来吧


public function TokenEncrypt(int $uid, $token, $key = "UF((&)(&^#&)@!")
{
   $encryptToken = base64_encode(openssl_encrypt("{$uid}:{$token}", 'DES-EDE3', $key, OPENSSL_RAW_DATA));
   return $encryptToken;
}


还有我们的数据库user表的结构

# Host: blog.95shouyou.com  (Version: 5.7.32-log)
# Date: 2020-12-31 14:04:11
# Generator: MySQL-Front 5.3  (Build 4.234)

/*!40101 SET NAMES utf8 */;

#
# Structure for table "user"
#

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL DEFAULT '' COMMENT '用户昵称',
  `token` varchar(128) NOT NULL DEFAULT '' COMMENT '微信token',
  `create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
  `pid` int(11) NOT NULL DEFAULT '0' COMMENT '邀请人',
  `openid` varchar(255) NOT NULL DEFAULT '' COMMENT '微信openid',
  `avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '用户头像',
  `sex` tinyint(3) NOT NULL DEFAULT '0' COMMENT '性别',
  `provider` char(32) NOT NULL DEFAULT '' COMMENT '用户渠道',
  PRIMARY KEY (`id`),
  KEY `openid` (`openid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='用户';


扫描二维码至手机访问

扫描二维码推送至手机访问。

版权声明:本文由何烦过虎溪发布,如需转载请注明出处。

转载请注明出处:http://95shouyou.com/?id=28

分享给朋友:

相关文章

Lumen框架报错Cannot declare class Event, because the name is already in use

Lumen框架报错Cannot declare class Event, because the name is already in use

Lumen框架报错信息Cannot declare class Event, because the name is already in use(1/1) ErrorExceptionCa...

laravel个推设置别名

laravel个推设置别名

上一篇文章我们说过了怎么用laravel接个推的官方sdk实现个推推送和厂商离线推送,因为我们要用到别名推送,而前端又用到的是unipush,在前端去绑定别名的难度肯定要大一点,所以就有一个思路就是,...

mysql查找附近的人,经纬度查询

经纬度排序mysql函数CREATE DEFINER=`root`@`localhost` FUNCTION `get_distance`(`lon1` float,`lat1` float,`lon...

Laravel带条件查询多个count

Laravel带条件查询多个count

在一个数据表中,我们需要用到聚合函数count来查询符合条件的总数。举例一个场景:我们有一个帖子,这个帖子可以分别被好中差评,好中差评记录用一个单独的记录表来存储。如果用户点击好评,那么该帖子作者的经...

php对接七牛云短信验证码实战

短信验证码登录的用处非常的大,登录,注册,修改密码,安全相关的啥都可以干。选定的七牛云短信是因为存储也是用的七牛云,七牛的sdk都加载进来了,也懒得去换其他的厂家了。下面上代码:Controller层...

利用workerman实现webrtc实时音视频通话

利用workerman实现webrtc实时音视频通话

实现原理利用workerman的websocket实现实时消息传递。webrtc自带p2p功能,利用STUN中继服务器实现webrtc实时音视频看看我们的前端文件,只是一个单页面<html>...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。