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

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

陈杰2年前 (2020-12-31)PHP2265

微信公众号授权登录实战


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

分享给朋友:

相关文章

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

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

Laravel记录SQL操作日志的方法

Laravel记录SQL操作日志的方法

在laravel中我们有一个需求就是,涉及到sql操作的update,insert,delete操作的语句,我们都要写一个日志来记录一下说说方法吧。在项目目录app/Providers/AppServ...

通过代码创建多个同样的mysql表

在分库分表中可能要同时创建多个结构相同但后缀不同的表,通过代码实现for ($i = 3; $i <= 20; $i++) {    DB::connection('...

Lumen框架报错Class session does not exist

Lumen框架报错Class session does not exist

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

laravel集成极光推送实战

公司项目需要用到app推送消息通知,市面上很多推送渠道商,选来选去最终选定了极光推送,因为项目使用laravel写的,laravel自身又有模型事件,所以研究了一下,在不改动原有代码的情况下,给项目加...

laravel通过模板html生成word文档

laravel通过模板html生成word文档

因为公司项目需要,内部的管理系统有一个php实时查询数据库,根据内容来生成word文档排版没有什么需求,实现原理是查询数据库,然后用laravel自带的模板引擎,生成一个html网页,然后修改网页的r...

发表评论

访客

看不清,换一张

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