关注公众号自动登录

采用:「实用」微信扫码 - 关注公众号后网站自动登录

上代码

前端部分代码

<script>
    // 方便清除轮询
    let timer = null


    // 请求登录二维码

    $('.wechat-login').click(function () {

        $.get("{{ route('wechat.login.pic') }}", function (result) {
            console.log(result)
            // 显示二维码图片
            $('.wechat-url').attr('src', result.url)
            // 轮询登录状态
            timer = setInterval(() => {
                // 请求参数是二维码中的场景值


                $.ajax({
                    type: "GET",
                    url: "{{ route('admin.login.check') }}",
                    data: {

                        'wechat_flag': result.weChatFlag
                    },
                    dataType: "json",
                    success: function (result) {
                        if (result.status == 'success') {
                            // alert(result.message)
                            window.location.href = result.data

                        } else if (result.status == 'error') {
                            alert(result.message)
                            window.location.reload()
                        }
                    },
                    error: function (e) {
                        console.log(e)
                    }
                });

            }, 2000)
        })


    })

    // 返回时清除轮询
    $('.wechat-back').click(function () {
        clearInterval(timer)
    })


</script>

后端部分代码

<?php

namespace App\Http\Controllers\Api;

use App\Models\AdminUser;
use Dcat\Admin\Models\Administrator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use App\Models\WeChatUser;
use Cache;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Dcat\Admin\Admin;

class WechatController extends Controller
{
    //
    protected $app;

    /**
     * Construct
     *
     * WeChatController constructor.
     */
    public function __construct()
    {
        $this->app = app('wechat.official_account');
    }

    /**
     * 获取二维码图片
     *
     * @param Request $request
     *
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function getWxPic(Request $request)
    {
        // 查询 cookie,如果没有就重新生成一次
        if (!$weChatFlag = $request->cookie(WeChatUser::WECHAT_FLAG)) {
            $weChatFlag = (string)Str::uuid();
        }
//        // 缓存微信带参二维码
        if (!$url = Cache::get(WeChatUser::QR_URL . $weChatFlag)) {
//            // 有效期 1 天的二维码
            $qrCode = $this->app->qrcode;
            $result = $qrCode->temporary($weChatFlag, 3600 * 24);
            // 图片链接
            $url = $qrCode->url($result['ticket']);

            Cache::put(WeChatUser::QR_URL . $weChatFlag, $url, now()->addDay());
        }

        return response(compact('url', 'weChatFlag'))
            ->cookie(WeChatUser::WECHAT_FLAG, $weChatFlag, 24 * 60);

    }

    /**
     * 微信消息接入(这里拆分函数处理)
     *
     * @return \Symfony\Component\HttpFoundation\Response
     * @throws \EasyWeChat\Kernel\Exceptions\BadRequestException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \ReflectionException
     */
    public function serve()
    {
        $app = $this->app;

        $app->server->push(function ($message) {
            if ($message) {
                $method = Str::camel('handle_' . $message['MsgType']);

                if (method_exists($this, $method)) {
                    $this->openid = $message['FromUserName'];

                    return call_user_func_array([$this, $method], [$message]);
                }

                //Log::info('无此处理方法:' . $method);
            }
        });


        return $app->server->serve();
    }

    /**
     * 事件引导处理方法(事件有许多,拆分处理)
     *
     * @param $event
     *
     * @return mixed
     */
    protected function handleEvent($event)
    {

        $method = Str::camel('event_' . $event['Event']);

        if (method_exists($this, $method)) {
            return call_user_func_array([$this, $method], [$event]);
        }

        //Log::info('无此事件处理方法:' . $method);
    }


    /**
     * 取消订阅
     *
     * @param $event
     */
    protected function eventUnsubscribe($event)
    {
        $weChatUser = WeChatUser::whereOpenid($this->openid)->first();
        $weChatUser->subscribe = 0;
        $weChatUser->subscribe_time = null;
        $weChatUser->save();
    }

    /**
     * 扫描带参二维码事件
     *
     * @param $event
     */
    public function eventSCAN($event)
    {

        if ($weChatUser = WeChatUser::whereOpenid($this->openid)->first()) {

            //Log::info($weChatUser);
            // 标记前端可登陆
            $this->markTheLogin($event, $weChatUser);

            return '「'.$weChatUser->nickname . '」登录乐校系统成功!';
        }
    }

    /**
     * 订阅
     *
     * @param $event
     *
     * @throws \Throwable
     */
    protected function eventSubscribe($event)
    {
        $openId = $this->openid;
        $weChatUser = WeChatUser::whereOpenid($openId)->first();

        if ($weChatUser) {
            // 标记前端可登陆
            $this->markTheLogin($event, $weChatUser);
            return;
        }
        // 微信用户信息
        $weChatUser = $this->app->user->get($openId);
        // 注册
        $result = DB::transaction(function () use ($openId, $event, $weChatUser) {
            $nickname = filterEmoji($weChatUser['nickname']);
            $uid = (string)Str::uuid();
            // 用户
            $user = AdminUser::create([
                'username' => $uid,
                'password' => Hash::make(time()),
                'name' => $nickname,
                'avatar' => $weChatUser['headimgurl'],

            ]);

            // 用户信息
            $weChatUser = $user->weChatUser()->create([
                'openid' => $openId,
                'nickname' => $nickname,
                'subscribe' => $weChatUser['subscribe'],
                'sex' => $weChatUser['sex'],
                'city' => $weChatUser['city'],
                'province' => $weChatUser['province'],
                'country' => $weChatUser['country'],
                'headimgurl' => $weChatUser['headimgurl'],
                'subscribe_time' => date('Y-m-d H:i:s', $weChatUser['subscribe_time']),
                'remark' => $weChatUser['remark']

            ]);

            // 用户权限
            DB::table('admin_role_users')->insert([
                'role_id' => 4,
                'user_id' => $user->id,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ]);


            Log::info('用户注册成功 openid:' . $openId);

            $this->markTheLogin($event, $weChatUser);
        });

        Log::debug('SQL 错误: ', [$result]);
    }

    /**
     * 标记可登录
     *
     * @param $event
     * @param $uid
     */
    public function markTheLogin($event, $weChatUser)
    {

        if (empty($event['EventKey'])) {
            return;
        }

        $eventKey = $event['EventKey'];

        // 关注事件的场景值会带一个前缀需要去掉
        if ($event['Event'] == 'subscribe') {
            $eventKey = Str::after($event['EventKey'], 'qrscene_');
        }


        // 标记前端可登陆
        Cache::put(WeChatUser::LOGIN_WECHAT . $eventKey, $weChatUser, now()->addMinute(30));

    }


    /**
     * 微信用户登录检查
     *
     * @param Request $request
     *
     * @return bool|\Illuminate\Http\JsonResponse
     */
    public function adminLoginCheck(Request $request)
    {
        // 判断请求是否有微信登录标识
        if (!$flag = $request->wechat_flag) {
            return $this->successResponse('二维码过期,请刷新页面重新扫描', false);
        }

        // 根据微信标识在缓存中获取需要登录用户的 UID

        if (!$weChatUser = Cache::get(WeChatUser::LOGIN_WECHAT . $flag)) {
            return $this->successResponse('请刷新页面重新扫描', false);
        }

        $user = $weChatUser->admin_user;
        if (empty($user)) {
            return $this->successResponse('请重新关注关注公众号', false);
        }

        Auth::guard(config('admin.auth.guard') ?: 'admin')->login($user, true);

        Cache::forget(WeChatUser::LOGIN_WECHAT . $flag);
        Cache::forget(WeChatUser::QR_URL . $flag);

        return $this->successResponse('登陆成功', true);
    }

    /**
     * 微信用户登录检查
     *
     * @param Request $request
     *
     * @return bool|\Illuminate\Http\JsonResponse
     */
    public function loginCheck(Request $request)
    {

    }

}

备案号:鲁ICP备17018368号-1