迈出脚步
体验世界

laravel框架下微信扫码关注公众号登录网站

学php、微信开发、laravel之类的,我都是野路子,没什么系统,所以很多时候去改别人开发好的模块,非常为难,还不如自己去折腾,因此,折腾出一个批代码,做个记录,当然,其实下面这几个函数也和laravel没啥关系,纯粹的php代码

首先写一个用于调用的公共类 WechatClass.php

<?php


namespace App\Myclass;

use App\Models\Access_token;
use App\Models\Wechat;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class WechatClass
{

    public static function curlGet($url) {
        $ch = curl_init();
        $headers[] = 'Accept-Charset:utf-8';
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }
    public static function curlPost($url, $data) {
        $ch = curl_init();
        $headers[] = 'Accept-Charset: utf-8';
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);
        curl_close($ch);
        $result = json_decode($result, true);

        if (isset($result['errcode'])) {
            return array('errcode' => $result['errcode']);
        } else {
            $result['errcode'] = 0;
            return $result;
        }
    }

    public static function checkSignature($signature, $timestamp, $nonce)
    {
        $token = TOKEN;
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        if ($tmpStr == $signature) {
            return true;
        } else {
            return false;
        }
    }

    public static function getUserinfo($openid, $access_token) {
        if ($access_token && $openid) {
//            $url = "https://api.weixin.qq.com/sns/userinfo?access_token=" . $access_token . "&openid=" . $openid . "&lang=zh_CN";
            $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=$access_token&openid=$openid&lang=zh_CN";
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            $output = curl_exec($ch);
            curl_close($ch);
            return json_decode($output, true);
        }
    }


    public static function getAccessToken() {
        $access_token=Access_token::orderBy('id','desc')->first();
        if($access_token){
            if(time() - $access_token->time < 7100){
                //dd($access_token->access_token);
                return $access_token->access_token;
            }
        }
        $appid = env('WECHAT_OFFICIAL_ACCOUNT_APPID');
        $secret = env('WECHAT_OFFICIAL_ACCOUNT_SECRET');
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $secret;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        curl_close($ch);
        $result = json_decode($output, true);
        DB::insert('insert into access_token (access_token,time) VALUES (?,?)',[$result['access_token'],time()]);
        return $result['access_token'];
    }

    public static function get_qrcode($scene_id,$logkey){

        $access_token = self::getAccessToken();
        $qrcode_url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=' . $access_token;

        $paras = array("scene_id"=>$scene_id,"logkey"=>$logkey);
        $post_data = array();
        $post_data['expire_seconds'] = 3600 * 24; //有效时间
        $post_data['action_name'] = 'QR_STR_SCENE';//字符串  QR_SCENE 数字

        $post_data['action_info']['scene']['scene_str'] = json_encode($paras); //传参二维码主键id,微信端可获取

        $json = self::curlPost($qrcode_url, json_encode($post_data));
        if (!$json['errcode']) {

            $ticket = $json['ticket'];
            $ticket_img = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' . urlencode($ticket);
            $png = fopen($ticket_img,'r');
            file_put_contents(dirname(dirname(dirname(__FILE__))).'/public/uploads/qrcode/'.$logkey.'.png',$png);
            return $ticket_img;
        } else {
            return false;
        }
    }
}

然后再在controller里面调用这个类

<?php

namespace App\Http\Controllers;

use App\Models\User;
use App\Models\Wechat;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\DB;
use Auth;
use Illuminate\Support\Str;
use App\Myclass\WechatClass;

define('TOKEN', 'weixin');

class WechatController extends Controller
{
    ///生成带参数的登录二维码
    public function index(){
        $logkey = Str::random(30);
        DB::insert('insert into wechat (time,logkey,log_type) VALUES (?,?,?)',[time(),$logkey,'login']);
        $scene_id=1;
        $ticket_img=WechatClass::get_qrcode($scene_id,$logkey);
        if ($ticket_img) {
            $title='微信扫码测试';
            return view('user.wechat',compact('title','ticket_img','logkey'));
        } else {
            return 'error';
        }
    }

    ///用于微信回调url
    public function callback(Request $request){
        $signature = $request->input('signature');
        $timestamp = $request->input('timestamp');
        $nonce = $request->input('nonce');
        $echoStr = $request->input('echostr');
        //if (WechatClass::checkSignature($signature, $timestamp, $nonce)) {
        $data = $request->all();
        if(isset($data['openid'])){
            $openid = $data['openid'];
            $access_token = WechatClass::getAccessToken();
            //return $access_token;
            $u = WechatClass::getUserinfo($openid, $access_token);

            $postStr = file_get_contents('php://input');
            $data = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            if($data->Event) {
                $FromUserName = $data->FromUserName; //openid
                $EventKey = $data->EventKey; //带前缀的Key
                $EventKey = ltrim($EventKey, 'qrscene_'); //去掉前缀就是我们传递给微信的Key

                $EventKey=json_decode($EventKey,true);
                $logkey=$EventKey['logkey'];
                $user = Wechat::where('logkey',$logkey)->first();
                $user->subscribe=$u['subscribe'];
                $user->openid=$u['openid'];
                $user->nickname=$u['nickname'];
                $user->sex=$u['sex'];
                $user->city=$u['city'];
                $user->province=$u['province'];
                $user->country=$u['country'];
                $user->headimgurl=$u['headimgurl'];
                $user->update();
                unlink(dirname(dirname(dirname(dirname(__FILE__)))).'/public/uploads/qrcode/'.$logkey.'.png');
            }
        }
        ob_end_clean(); //必须清空缓冲区
        return $echoStr;
        //} else {
        // return 'Token verification failed.';
        // }
    }

    ///检查登录状态
    public function check_auth(Request $request){
        $logkey=$request->input('key');
        $wechat = Wechat::where('logkey',$logkey)->first();
        //dd($wechat->openid);
        if($wechat->openid){
            $user = User::where('openid',$wechat->openid)->first();
            if(!$user){
                $array=[
                    'name'=>$wechat->nickname,
                    'openid'=>$wechat->openid,
                    'created_at'=>date('Y-m-d H:i:s'),
                    'updated_at'=>date('Y-m-d H:i:s'),
                    'password'=>bcrypt('power123456'),
                    'log_type'=>$wechat->log_type,
                    'img'=>$wechat->headimgurl
                ];
                $result = User::create($array);
            }else{
                $user->lasttime=date('Y-m-d H:i:s');
                $user->log_type=$wechat->log_type;
                $user->img=$wechat->headimgurl;
                $user->update();
                $result = $user;
            }
            //Cookie::queue('img',urldecode($wechat->headimgurl),60*24);
            Auth::login($result, true);
            //$wechat->delete();
            return 1;
        }
        else{
            return 0;
        }
    }

}

记得将类文件加入composer中

autoload: {
   "classmap": [
            "database",
            "app/Myclass/WechatClass.php"
        ],
    "psr-4": {
            "App\\": "app/"
        }
    },

然后运行以下命令

composer dumpautoload

注意:

1、callback的路由要用any,另外在Middleware/VerifyCsrfToken.php中将改一下post验证例外

protected $except = [
         'wechat',
         'callback',
    ];

2、blade文件中这样写

@extends('user.header')
@section('content')
   <script src="{{asset('layouts/common/jquery.js')}}"></script>
    <img src="{{$ticket_img}}" alt="" width="200px">

    <script language="javascript" type="text/javascript">

        $(document).ready(function(e) {
            getRemote();
        });

        function getRemote () {
            $.getJSON("{{url('check_auth/?key='.$logkey)}}", function (data) {
                console.log(data);
                // console.log(result);
                if(data===1){
                    location.href ="{{url('user/profile')}}";
                }
            })
            setTimeout(getRemote,2000);
        }
    </script>

@endsection

赞(1) 喜欢我
未经允许不得转载:王威 » laravel框架下微信扫码关注公众号登录网站
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏