网站内容自动更新(第二种扫码登录的原理很简单,核心就是依靠微信带参二维码、EasyWeChat二维码文档简单的解释一下扫描)

优采云 发布时间: 2021-11-21 13:31

  网站内容自动更新(第二种扫码登录的原理很简单,核心就是依靠微信带参二维码、EasyWeChat二维码文档简单的解释一下扫描)

  前期准备

  其实二次扫码登录的原理很简单,核心就是依靠微信二维码带参数,EasyWeChat二维码文档

  简单解释一下带参数扫描这个二维码的区别:

  看到这里,相信你已经明白了,整理一下:

  实战请求登录二维码

  前端通过点击事件请求微信登录二维码

  // 方便清除轮询

let timer = null

$(document).on('click', '.wechat-login', function () {

// 请求登录二维码

axios.get('{{ route('wx.pic') }}').then(response => {

let result = response.data

if (result.status_code !== 200) {

return

}

// 显示二维码图片

$('.wechat-url').attr('src', result.data.url)

// 轮询登录状态

timer = setInterval(() => {

// 请求参数是二维码中的场景值

axios.get('{{ route('home.login.check') }}', {params: {wechat_flag: result.data.weChatFlag}}).then(response => {

let result = response.data

if (result.data) {

window.location.href = '/'

}

})

}, 2000)

})

})

// 返回时清除轮询

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

clearInterval(timer)

})

  后端带参数生成二维码逻辑,EasyWeChat配置请参考文档

  

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(WxUser::WECHAT_FLAG)) {

$weChatFlag = Uuid::uuid4()->getHex();

}

// 缓存微信带参二维码

if (!$url = Cache::get(WxUser::QR_URL . $weChatFlag)) {

// 有效期 1 天的二维码

$qrCode = $this->app->qrcode;

$result = $qrCode->temporary($weChatFlag, 3600 * 24);

$url = $qrCode->url($result['ticket']);

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

}

// 自定义参数返回给前端,前端轮询

return $this->ajaxSuccess(compact('url', 'weChatFlag'))

->cookie(WxUser::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 = camel_case('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)

{

Log::info('事件参数:', [$event]);

$method = camel_case('event_' . $event['Event']);

Log::info('处理方法:' . $method);

if (method_exists($this, $method)) {

return call_user_func_array([$this, $method], [$event]);

}

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

}

/**

* 取消订阅

*

* @param $event

*/

protected function eventUnsubscribe($event)

{

$wxUser = WxUser::whereOpenid($this->openid)->first();

$wxUser->subscribe = 0;

$wxUser->subscribe_time = null;

$wxUser->save();

}

/**

* 扫描带参二维码事件

*

* @param $event

*/

public function eventSCAN($event)

{

if ($wxUser = WxUser::whereOpenid($this->openid)->first()) {

// 标记前端可登陆

$this->markTheLogin($event, $wxUser->uid);

return;

}

}

/**

* 订阅

*

* @param $event

*

* @throws \Throwable

*/

protected function eventSubscribe($event)

{

$openId = $this->openid;

if ($wxUser = WxUser::whereOpenid($openId)->first()) {

// 标记前端可登陆

$this->markTheLogin($event, $wxUser->uid);

return;

}

// 微信用户信息

$wxUser = $this->app->user->get($openId);

// 注册

$nickname = $this->filterEmoji($wxUser['nickname']);

$result = DB::transaction(function () use ($openId, $event, $nickname, $wxUser) {

$uid = Uuid::uuid4()->getHex();

$time = time();

// 用户

$user = User::create([

'uid' => $uid,

'created_at' => $time,

]);

// 用户信息

$user->user_info()->create([

'email' => $user->email,

'nickname' => $nickname,

'sex' => $wxUser['sex'],

'address' => $wxUser['country'] . ' ' . $wxUser['province'] . ' ' . $wxUser['city'],

'avatar' => $wxUser['headimgurl'],

'code' => app(UserRegisterController::class)->inviteCode(10),

'created_at' => $time,

]);

// 用户账户

$user->user_account()->create([

'gold' => 200,

'created_at' => $time,

]);

$wxUserModel = $user->wx_user()->create([

'subscribe' => $wxUser['subscribe'],

'subscribe_time' => $wxUser['subscribe_time'],

'openid' => $wxUser['openid'],

'created_at' => $time,

]);

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

$this->markTheLogin($event, $wxUserModel->uid);

});

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

}

/**

* 标记可登录

*

* @param $event

* @param $uid

*/

public function markTheLogin($event, $uid)

{

if (empty($event['EventKey'])) {

return;

}

$eventKey = $event['EventKey'];

// 关注事件的场景值会带一个前缀需要去掉

if ($event['Event'] == 'subscribe') {

$eventKey = str_after($event['EventKey'], 'qrscene_');

}

Log::info('EventKey:' . $eventKey, [$event['EventKey']]);

// 标记前端可登陆

Cache::put(WxUser::LOGIN_WECHAT . $eventKey, $uid, now()->addMinute(30));

}

  前端登录检查

   /**

* 微信用户登录检查

*

* @param Request $request

*

* @return bool|\Illuminate\Http\JsonResponse

*/

public function loginCheck(Request $request)

{

// 判断请求是否有微信登录标识

if (!$flag = $request->wechat_flag) {

return $this->ajaxSuccess(false);

}

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

$uid = Cache::get(WxUser::LOGIN_WECHAT . $flag);

$user = User::whereUid($uid)->first();

if (empty($user)) {

return $this->ajaxSuccess(false);

}

// 登录用户、并清空缓存

auth('web')->login($user);

Cache::forget(WxUser::LOGIN_WECHAT . $flag);

Cache::forget(WxUser::QR_URL . $flag);

return $this->ajaxSuccess(true);

}

  OK,一个很实用的功能,赶紧加入你的项目吧!

  聚苯乙烯

  感谢您关注“GitHub Hot”公众号,为您展示科技圈的热点和新鲜事物!

  

  本作品采用《CC协议》,转载须注明作者及本文链接

  感谢您关注“GitHub Hot”公众号

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线