微信公众号网页授权,进行用户扫码登录

逻辑总结

以fastadmin后台会员为例,缺少字段请自行在数据表中添加。

1.在后台添加会员,并修改user表,新增如下字段

字段名                   类型                长度         小数点    不是null           键                 注释

verification            varchar            255            0             0                    0                验证            
wx_openid            varchar            255            0             0                    0                微信用户openid        
wx_nickname       varchar            255            0             0                    0                微信用户名          
wx_headimgurl     varchar            255            0             0                    0                微信用户头像         
wx_state              varchar             255            0             0                    0                自定义微信标识         
power_gzh          mediumtext       0                0            0                     0                公众号权限            

2.添加会员

3.对指定账号进行微信扫码绑定用户openid,一定得是完整授权的opendi

4.扫描登录二维码获取用户信息修改登录状态

第一步,微信授权url生成二维码扫码获取用户code

/**
 * 登录-微信扫码
* @ApiReturn   ({
"code": 0,
"msg": "请求成功",
"time": "1684717960",
"data": "<img src=\"/static/login/qrcode/1684717960.8303.png\" alt=\"扫码登录\" style=\"width:240px\">"
 * })
 */
public function ewmlogin(){
    $state = md5(uniqid(rand(), true));        //用于前端登录状态判断
    Session::set('state',$state);
    //构造微信授权登录的URL
    $authURL = 'https://open.weixin.qq.com/connect/oauth2/authorize';
    $authURL .= '?appid=' . $this->wechatAppID;
    $authURL .= '&redirect_uri='.$this->wechatRedirectURL;
    $authURL .= '&response_type=code';
    $authURL .= '&scope=snsapi_base';
    $authURL .= '&state='.$state;
    $authURL .= '#wechat_redirect';
  //  return($authURL);
    //https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxe772ecaab712dd7f&redirect_uri=https://wechat.xuekao123.com/api/Wx_login/redirect.html&response_type=code&scope=snsapi_base&state=5#wechat_redirect
    //用url生成二维码保存至服务器,并将图片地址返回给前端进行渲染
    $erweimaImg = $this->erweima($authURL);
  //  $this->success("请求成功", $erweimaImg, 0);
    $this->success("请求成功", ['state'=>$state,"erweima"=>$erweimaImg] , 0);
}
/**
 * 生成二维码
 * @ApiInternal
 * @param string access_token
 * @param string openid
 * @return array
 */
function erweima($url = '')
{
    require_once '../vendor/phpqrcode/phpqrcode.php';
    $qrcode = new \QRcode();
    $value = $url;         //二维码内容
    $errorCorrectionLevel = 'H';  //容错级别
    $matrixPointSize = 6;      //生成图片大小
    //生成二维码图片
    $filename = 'static/login/qrcode/' . microtime(true) . '.png';
    $qrcode->png($value, $filename, $errorCorrectionLevel, $matrixPointSize, 2);
    $logo = 'static/image/logo.jpg'; //准备好的logo图片
    $QR = $filename;      //已经生成的原始二维码图
    if (file_exists($logo)) {
        $QR = imagecreatefromstring(file_get_contents($QR));    //目标图象连接资源。
        $logo = imagecreatefromstring(file_get_contents($logo));  //源图象连接资源。
        $QR_width = imagesx($QR);      //二维码图片宽度
        $QR_height = imagesy($QR);     //二维码图片高度
        $logo_width = imagesx($logo);    //logo图片宽度
        $logo_height = imagesy($logo);   //logo图片高度
        $logo_qr_width = $QR_width / 4;   //组合之后logo的宽度(占二维码的1/5)
        $scale = $logo_width / $logo_qr_width;  //logo的宽度缩放比(本身宽度/组合后的宽度)
        $logo_qr_height = $logo_height / $scale; //组合之后logo的高度
        $from_width = ($QR_width - $logo_qr_width) / 2;  //组合之后logo左上角所在坐标点
        //重新组合图片并调整大小
        /*
         * imagecopyresampled() 将一幅图像(源图象)中的一块正方形区域拷贝到另一个图像中
         */
        imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);
    }
    //输出图片
    // echo $QR;

    $im = imagecreatefrompng($QR);
    // imagepng($im);
    imagedestroy($im);
 //   return '<img src="/' . $filename . '" alt="扫码登录" style="width:240px">';
    return '/' . $filename;
}

第二步,回调使用用户code获取用户access_token

/**
 * 微信扫码回调
 * @ApiInternal
 */
public function redirect()
{
    //获取到code和state
    $param = $this->request->param();

    //获取到access_token、expires_in、refresh_token、openid、scope
    $accessToken = $this->getAccessToken($param['code']);

    //未授权完整信息则提示用户授权
    if(isset($accessToken['is_snapshotuser']))    return ("<div><h1>请点击下方授权完整信息!</h1></div>");

    //获取用户信息
        $wxuserinfo = $this->getWxUserInfo($accessToken['access_token'],$accessToken['openid']);
    if(strlen($param['state'])<16)
    {
        //账号绑定
        $id = $param['state'];
        $data = User::get($id);
        if(!$data) $this->error("参数错误 (invalid parameter)", null, ApiErrorCode::$ParameterError);
        if($data->wx_openid) $this->error("绑定失败,该账号已被绑定!", null, 1);
        if(User::get(["wx_openid"=>$wxuserinfo['openid']])) $this->error("绑定失败,该微信已绑定其他账号!", null, 1);
        $data->wx_openid = $wxuserinfo['openid'];
        $data->wx_nickname = $wxuserinfo['nickname'];
        $data->wx_headimgurl = $wxuserinfo['headimgurl'];
        $result = $data->save();
        if(!$result) $this->error("账号绑定失败", null, 1);
        return ("<div><h1>扫码成功!</h1></div>");
      //  $this->success("请求成功", '', 0);
    }else{
        //扫码登录(即存入state值)
        if($wxuserinfo){
                $user = User::get(["wx_openid" => $accessToken['openid']]);
                if(!$user) $this->error("扫码失败,请联系技术管理人员绑定账号!", null, 1);
                $user->wx_nickname = $wxuserinfo['nickname'];
                $user->wx_headimgurl = $wxuserinfo['headimgurl'];
                $user->wx_state = $param["state"];
                $user->save();

        }
        return ("<div><h1>扫码成功!</h1></div>");
      //  $this->success("扫码成功!", '', 0);
    }

}
/**
 * 获取access_token
 * @ApiInternal
 */
public function getAccessToken($code = '')
{
    if (!$code) {
        return [];
    }
    $queryarr = array(
        "appid"      => $this->wechatAppID,
        "secret"     => $this->wechatAppSecret,
        "code"       => $code,
        "grant_type" => "authorization_code",
    );
    $response = Http::get('https://api.weixin.qq.com/sns/oauth2/access_token', $queryarr);
    $ret = (array)json_decode($response, true);
    return $ret ? $ret : [];
}

/**
 * 获取微信用户信息
 * @ApiInternal
 * @param string access_token
 * @param string openid
 * @return array
 */
public function getWxUserInfo($access_token = '' , $openid = '')
{
    $queryarr = [
        "access_token" => $access_token,
        "openid"       => $openid,
        "lang"         => 'zh_CN'
    ];
    $ret = Http::get('https://api.weixin.qq.com/sns/userinfo', $queryarr);
    $ret = (array)json_decode($ret, true);
    return $ret ? $ret : [];
}

第三步,回调中使用用户access_token获取用户信息

/**
 * 获取微信用户信息
 * @ApiInternal
 * @param string access_token
 * @param string openid
 * @return array
 */
public function getWxUserInfo($access_token = '' , $openid = '')
{
    $queryarr = [
        "access_token" => $access_token,
        "openid"       => $openid,
        "lang"         => 'zh_CN'
    ];
    $ret = Http::get('https://api.weixin.qq.com/sns/userinfo', $queryarr);
    $ret = (array)json_decode($ret, true);
    return $ret ? $ret : [];
}

第四步,回调中获取用户完整授权的openid进行账号绑定

 /**
  * 账号绑定
  * @ApiParams   (name="id", type="int", required=true, description="会员id")
  * @ApiReturn   ({
图片html标签
  * })
  */
 public function bind(){
    $id = $this->request->param("id");
    if(!$id) $this->error("参数错误 (invalid parameter)", null,  ApiErrorCode::$ParameterError);
     //构造微信授权登录的URL
     $authURL = 'https://open.weixin.qq.com/connect/oauth2/authorize';
     $authURL .= '?appid=' . $this->wechatAppID;
     $authURL .= '&redirect_uri='.$this->wechatRedirectURL;
     $authURL .= '&response_type=code';
     $authURL .= '&scope=snsapi_base';
     $authURL .= '&state='.$id;
     $authURL .= '#wechat_redirect';
     $erweimaImg = $this->erweima($authURL);
     echo $erweimaImg;
 }

第五步,前端接口登录判定

/**
 *  扫码判断及登录
 * @ApiMethod   (POST)
 * @ApiParams   (name="state", type="int", required=true, description="登录状态码")
 * @ApiReturn   ({
"code": 0,
"msg": "已登录",
"time": "1684484807",
"data": {
"token": "962c5546-e344-4a2d-be5e-79186338678d"
}
  })
 */
public function isLogin()
{
    header('Content-type:text/json; charset=utf-8');
    //需post请求
    if(!Request::instance()->isPost()) $this->error("需要 POST 请求", null, 43002);
    $state = $this->request->param('state');
    if(!$state) $this->error("参数错误 (invalid parameter)", null, c);
    $result = User::where("wx_state",$state)->find();

    if($result) {
        if(!Cookie::get('token'))
        {
            $id = openssl_encrypt($result->id, 'AES-128-ECB', '1236768886123456', OPENSSL_RAW_DATA);
            if ($this->auth->login('','',$id)) {
                $userInfo = $this->auth->getUserinfo();
                Cookie::set("token",$userInfo['token'],0);
                $this->success("已登录", ['token'=>$userInfo['token']], 0);
            } else {
                $this->error(__('Please login first'), null, 401);
            }
        }
    
        $data = $this->auth->getUserinfo();
        $this->success("已登录", ['token'=>$data['token']], 0);
    }
    $this->error('请先扫码', null, 1);
}

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Flask是一种轻量级的Python Web框架,能够方便地构建网页应用程序。要实现微信公众号扫码关注并登录网页功能,可以使用Flask结合微信开发接口进行实现。 首先,需要在微信公众平台上注册并创建一个公众号,并获取到相关的开发者ID和密钥。 接下来,搭建Flask应用程序,先安装Flask库,并导入相关的依赖库,如wechatpy和requests库等。 然后,创建一个Flask路由,用于接收微信服务器的验证请求和菜单跳转等请求。根据微信开发文档,编写逻辑代码,进行验证和处理微信服务器的各种请求。 在处理菜单跳转请求时,可以通过微信JS-SDK提供的扫一扫功能,生成一个特定的二维码,用于用户关注公众号。二维码中包含一个唯一的标识码,用于识别用户公众号之间的关系。 当用户扫描二维码关注公众号后,微信服务器会向事先设置的回调URL发送消息通知。在Flask应用程序中,可以通过编写对应的路由来处理该通知,获取用户的唯一标识码。然后,可以将该标识码与用户相关的信息存储到数据库中,以便后续使用。 最后,通过编写相关的路由和模板,实现用户登录网页功能。当用户点击网页中的登录按钮时,可以跳转到微信授权登录页面。用户授权后,微信会将用户的唯一标识码和相关信息返回到事先设置的回调URL。在Flask应用程序中,处理该回调URL的路由中,可以获取用户的标识码,从数据库中获取用户信息,并进行登录操作。 综上所述,通过使用Flask框架结合微信开发接口,可以实现微信公众号扫码关注并登录网页功能。这样的实现方式能够方便地与微信公众号进行交互,并提供给用户一个方便、安全的登录方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值