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

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

陈杰4个月前 (12-31)PHP711

微信公众号授权登录实战


框架: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

分享给朋友:

相关文章

laravel的Observer观察者模式模型事件实战

laravel的orm特别好用,特别是observer观察者模式,可以在不更改原有业务代码的情况下做到切入编程,有点类似于我们之前常用的钩子函数。下面就是我们深入observer观察者模式的实战代码现...

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

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

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

通过supervisor管理laravel的queue队列

通过supervisor管理laravel的queue队列

配置文件[program:queue]command=php artisan queue:work redis --tries=3 --delay=3directory=/www/wwwroot/sh...

Lumen框架报错Class session does not exist

Lumen框架报错Class session does not exist

由于lumen框架是为速度而生的 Laravel 框架,所以移除了session的支持,虽然在ide中代码提示可以敲出Session::put()方法出来,但是最终还是提示的是Class sessio...

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分表model映射的思路

预先估计会出现大数据量并且访问频繁的表,将其分为若干个表这种预估大差不差的,论坛里面发表帖子的表,时间长了这张表肯定很大,几十万,几百万都有可能。 聊天室里面信息表,几十个人在一起一聊一个晚上,时间长...

发表评论

访客

看不清,换一张

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