使用场景:当总平台生产二维码,使用绑定门店的微信号扫码进行登录到门店的后台。
流程:
1.使用特殊入口,方便特殊处理;生产供绑定门店的微信扫码的小程序码:当然主要的核心是使用token校验,login方法就是生成了特殊的token保存入库!!!!
//返回供微信扫的小程序码方法。
public function actionLogin($_platform = 'wx')
{
$m = new UserAuthLogin();
$img_url = null;
$error = null;
if ($_platform) {
$m->store_id = $this->store->id;
if($_platform == 'my'){
$m->token = 'token=' .md5(uniqid());
}else{
$m->token = md5(uniqid());
}
$m->addtime = time();
$m->save();
$res = GenerateShareQrcode::getQrcode($this->store->id, $m->token, 430, 'pages/web/login/login');
if ($res['code'] == 0) {
$img_path = str_replace('\\', '/', $res['file_path']);
$img_url = mb_substr(\Yii::$app->request->baseUrl, 0, -4) . '/' . mb_substr($img_path, mb_stripos($img_path, 'runtime/image/'));
//将本机图片上传到云存储服务器
$img = postUploadImg($this->store->id, $img_path, sha1_file($img_path). '.jpg');
if ($img) {
$img_url = $img;
}
} else {
$error = $res['msg'];
}
}
return $this->render('login', [
'error' => $error,
'token' => $m->token,
'img_url' => $img_url,
'_platform' => $_platform,
]);
}
页面接收方法返回的参数进行轮训观察是否小程序码被扫码;PS:当然这个小程序码是要在微信那边生产的;上面的getQrcode方法就是微信api为了生产供扫的小程序码图片的;只是我们把它存起来到我们的服务器而已。如下代码携带token轮询!!!!!
<?php
/**
* Created by IntelliJ IDEA.
* User: Administrator
* Date: 2018/3/9
* Time: 10:28
*/
?>
<style>
body {
background: #f7f6f1;
}
.main-box {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.main-content {
max-width: 260px;
}
.title {
text-align: center;
padding: 16px;
font-size: 1.35rem;
}
.qrcode {
max-width: 260px;
border-radius: 0;
border: 1px solid #eee;
margin-bottom: 20px;
padding: 1rem;
background-color: #fff;
}
.desc {
background: #eee;
max-width: 100%;
text-align: center;
padding: 12px;
border-radius: 999px;
box-shadow: inset 1px 1px 3px 0px rgba(0, 0, 0, .2), 1px 1px 1px #fff;
}
.login-success {
color: #1f9832;
display: none;
}
.platform-item {
text-decoration: none;
text-align: center;
padding: .5rem;
margin: 0 1rem;
}
</style>
<div class="main-box" flex="dir:left main:center cross:center">
<?php if ($_platform == 'wx'): ?>
<div class="main-content">
<div class="title">微信登陆</div>
<img class="qrcode" src="<?= $img_url ?>">
<div class="desc">
<div class="login-tip">请使用微信扫描小程序码登录</div>
</div>
</div>
<?php elseif ($_platform == 'my'): ?>
<div class="main-content">
<div class="title">支付宝登录</div>
<img class="qrcode" src="<?= $img_url ?>">
<div class="desc">
<div class="login-tip">请使用支付宝扫描小程序码登录</div>
</div>
</div>
<?php else: ?>
<div class="main-content">
<div class="title"></div>
<div flex="dir:left main:center">
<a class="platform-item"
href="<?= Yii::$app->request->baseUrl ?>/store.php?store_id=<?= Yii::$app->request->get('store_id') ?>&_platform=wx">
<div>
<img style="width: 100px;height: 100px"
src="https://open.weixin.qq.com/zh_CN/htmledition/res/assets/res-design-download/icon64_appwx_logo.png">
</div>
<div>微信用户</div>
</a>
<!--<a class="platform-item"
href="<?= Yii::$app->request->baseUrl ?>/store.php?store_id=<?= Yii::$app->request->get('store_id') ?>&_platform=my">
<div>
<img style="width: 100px;height: 100px"
src="<?= Yii::$app->request->baseUrl ?>/statics/images/alipay.png">
</div>
<div>支付宝用户</div>
</a>-->
</div>
</div>
<?php endif; ?>
</div>
<script>
var stop = false;
var token = '<?=$token?>';
function checkLogin() {
if (stop)
return;
if (!token || token == '')
return;
$.ajax({
url: '<?=Yii::$app->urlManager->createUrl(['shop/passport/check-login',])?>',
data: {
token: token,
},
dataType: 'json',
success: function (res) {
$('.login-tip').text(res.msg);
if (res.code == 1) {
stop = true;
}
if (res.code == 0) {
location.href = '<?=Yii::$app->urlManager->createUrl(['shop'])?>';
}
if (res.code == -1) {
checkLogin();
}
},
error: function () {
stop = true;
}
});
}
checkLogin();
</script>
2.那么问题来了微信用户扫码时是怎么处理的呢?怎么判断哪些微信号是绑定了门店的呢?不急,慢慢说。不知道你有没有注意到这个方法:;
它就是告诉微信服务器那边,当用户扫码时,调用哪个小程序方法,并且给小程序token;当然这个token是我们后台入库保存的。
//小程序接口方法;接收微信服务器端返回的token;
public function actionWebLogin($token)
{
$m = UserAuthLogin::findOne([
'token' => $token,
'store_id' => $this->store->id,
]);
if (!$m) {
return new BaseApiResponse([
'code' => 1,
'msg' => '错误的小程序码,请刷新网页重试'
]);
}
if ($m->is_pass != 0) {
return new BaseApiResponse([
'code' => 1,
'msg' => '您已处理过,请勿重复提交'
]);
}
$m->user_id = \Yii::$app->user->id;
$m->is_pass = 1;
$m->save();
return new BaseApiResponse([
'code' => 0,
'msg' => '已确认登录'
]);
}
3.上面说到,login那个页面会一直轮训,等待用户扫码;那么问题来了?如果用户一直不扫码怎么办?
public function actionCheckLogin($token)
{
if (!$token) {
return [
'code' => 1,
'msg' => 'token不能为空',
];
}
for ($i = 0; $i < 3; $i++) {
$m = UserAuthLogin::findOne(['token' => $token]);
if (!$m) {
return [
'code' => 1,
'msg' => '错误的token',
];
}
if ($m->is_pass == 0) {
sleep(3);
}
if ($m->is_pass == 1) {
$user = User::findOne($m->user_id);
$shop = Shop::find()->where(['store_id' => $this->store->id, 'user_id' => $m->user_id, 'is_delete' => 0])->one();
if (!$shop) {
return [
'code' => ApiCode::CODE_ERROR,
'msg' => '此用户暂未关联门店,请联系管理员'
];
}
\Yii::$app->shop->login($user);
\Yii::$app->session->set('store_id', $this->store->id);
return [
'code' => ApiCode::CODE_SUCCESS,
'msg' => '登录成功',
];
}
}
return [
'code' => -1,
'msg' => '请扫描小程序码登录',
];
}
4.扫码成功登陆;基本表设计如图