精华内容
下载资源
问答
  • <div><p>请问在多账号环境下 在 application_controller.rb 中 如何配置 wechat_api 和 wechat_oauth2 ? <code>wechat_api account: params[:account].to_sym 是无法获取 params 参数的</p><p>该提问来源于...
  • linux+apache+mod_python+wechat_sdk搭建微信公共账号服务器转载请注明本文原作者:FignerLiuPRE最近尝试了下使用python搭建微信公共账号服务器,实现了简单的消息收发功能。其中遇到了很多问题,特此记录下来。...

    linux+apache+mod_python+wechat_sdk搭建微信公共账号服务器

    转载请注明本文原作者:FignerLiu

    PRE

    最近尝试了下使用python搭建微信公共账号服务器,实现了简单的消息收发功能。其中遇到了很多问题,特此记录下来。

    服务器的选择

    如果使用python做开发语言,一般选用以下几种服务器可以用来做微信公共账号服务器(如果不全,欢迎大家补充):

    SAE + wsgi

    apache + mod_python

    apache + mod_wsgi

    nginx + wsgi

    如果对使用独立的服务器没有需求,或者对apache和nginx的配置不熟悉,一般采用SAE + wsgi做服务器。由于手头正好有闲置的Apache,本着生命在于折腾,从折腾中学习的目的,我选择了apache + mod_python作为我的服务器。以下的内容均以此为背景。

    在后面的开发过程中我体会到,我的这个选择绝对是最折腾人的 = 。=

    sdk的选择

    除了微信官方的sdk外,github上找到两个第三方sdk:

    wechat-python-sdk

    WeRoBot

    这两个sdk各有优劣,wechat-python-sdk代码更简洁易懂,而WeRoBot功能更全,包含微信支付API操作类等wechat-python-sdk不具有的功能。本次我选择使用了wechat-python-sdk

    服务器搭建与配置

    首先操作系统我选择的是放在阿里云上的centos 5.10

    需要安装如下软件包:

    apache 我选用的是httpd-2.4.10

    expat expat是用来解析xml等文件的库,我选用的是expat-2.0.1.tar.gz

    apr Apache Portable Runtime我选用的是apr-1.5.1.tar.gz

    apr-util 我选用的是apr-util-1.5.4.tar.gz

    prce Perl Compatible Regular Expressions 我选用的是pcre-8.36.tar.gz 。 上述expat,apr,apr-util,prce均为安装Apache时的依赖项,注意各软件包的版本,如果不一致可能导致不兼容的问题。

    mod_python Apache处理python的模块,我选用的是mod_python-3.5.0.tgz

    python-devel mod_python的安装依赖项,我选用的是python-devel-2.6.6-52.el6.x86_64,应和系统使用的python版本一致。

    python-pip python库安装工具,用来安装wechat-sdk

    wechat-sdk 微信平台第三方sdk

    virtualenv(可选) virtualenv的简介

    首先安装各软件包

    为了统一和方便,我把所有软件包都安装到了/usr/local下,均为编译安装。

    以下是部分安装配置命令

    #pcre

    ./configure --prefix=/usr/local/pcre

    #apr

    ./configure --prefix=/usr/local/apr

    #apr-util

    ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr --with-expat=/usr/local/expat/#apache

    ./configure --prefix=/usr/local/apache --with-expat=/usr/local/epxat --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-pcre=/usr/local/pcre/或者

    ./configure --prefix=/usr/local/apache --with-expat=/usr/local/epxat --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-pcre=/usr/local/pcre/#mod_python

    ./configure --prefix=/usr/local/mod_python --with-apxs=/usr/local/apache/bin/apxs

    除wechat-sdk外,安装命令均为make && make install。wechat-sdk安装方法为pip install wechat-sdk

    配置apache

    首先将Apache配置为自启动服务,可参考这篇文章

    服务启动成功后,在浏览器输入你的服务器ip,可看到如下It works! 字样,则表示Apache安装成功。接下来修改Apache配置文件,打开文件/usr/local/apache/httpd.conf,分别在对应位置添加如下配置

    在下面添加

    SetHandler mod_python

    PythonHandler index

    PythonDebugOnOrder allow,deny

    Allow from all

    在下面添加

    Alias /mywechat "/usr/local/apache/htdocs/daemon/webchat/mywechat.py"

    上面的配置的意思是:1.告诉Apache,目录/usr/local/apache/htdocs/daemon/webchat将使用mod_python处理客户端请求,所有请求交给这个目录下的index.py来处理;2.告诉Apache,为路径/usr/local/apache/htdocs/daemon/webchat/mywechat.py起了个别名,当客户端访问/mywechat的时候,实际上就是在访问/usr/local/apache/htdocs/daemon/webchat。

    注,上述配置需要设置了DocumentRoot为/usr/local/apache/htdocs才有效

    功能开发

    接下来我们只需要向index.py和mywechat.py中添加对应的请求处理逻辑即可!

    我们实现最简单的功能,即接收服务器请求,并给客户端发送消息。

    要完成这一步,我们首先要了解我们都可能收到哪些请求,以及这些请求的作用。

    首先在你登录微信公共账号,并点击成为开发者后,系统会让你验证你的服务器配置,这时微信公共平台服务器会向你的系统发送一个GET请求,来验证你的服务器,你需要按照微信制定的规则来返回验证信息。

    当验证通过后,微信普通用户向你发送消息时,普通用户会发送给你的服务器一个POST请求,这个请求将请求内容包含在一个xml文档中。

    简单来说,你需要处理这两种正常请求。此外,在你公共账号投入商业使用之前,还需要能够处理别人伪造的非法请求,从而避免信息被窃取。

    示例代码

    index.py

    #encoding:utf-8

    from mod_python importapacheimportosdefhandler(req):

    handler= req.uri[req.uri.rfind('/')+1:]if handler[-3:] == ".py":

    handler= handler[0:-3]if not handler == "index":

    req.add_handler("PythonHandler", handler);else:

    req.write("using the default handler : index")return apache.OK

    mywechat.py

    #-*- coding: utf-8 -*-#!/usr/bin/python

    from mod_python importapachefrom mod_python importutilimportosfrom wechat_sdk importWechatBasicimportsysimport_apache

    parse_qsl=_apache.parse_qsldefhandler(req):

    req.no_cache=True

    wechat= WechatBasic(token='yourtoken')if req.method == "GET":

    req.content_type= "text/plain"args=req.args

    apache.log_error("get req caught!!!")

    check(req,wechat)elif req.method == "POST":

    req.content_type= "text/xml"apache.log_error("post req caught!!!")

    parse(req,wechat)else:

    apache.log_error("unknown req method")returnapache.OKdefcheck(req,wechat):

    parameters=util.FieldStorage(req)

    apache.log_error(str(parameters))

    signature= parameters.get('signature',None)

    timestamp= parameters.get('timestamp',None)

    nonce= parameters.get('nonce',None)

    echostr= parameters.get('echostr','')if wechat.check_signature(signature=signature, timestamp=timestamp, nonce=nonce):

    apache.log_error("check succeed")

    req.write(echostr)returnapache.OKelse:

    apache.log_error("check failed")returnapache.HTTP_UNAUTHORIZEDdefparse(req,wechat):#get request body

    try:

    clen= int(req.headers_in["content-length"])except(KeyError,ValueError):raiseapache.SERVER_RETURN(apache.HTTP_LENGTH_REQUIRED)

    req_body=req.read(clen)

    apache.log_error(req_body)#parse body

    try:

    wechat.parse_data(req_body)

    message=wechat.get_message()

    response=Noneif message.type == 'text':if message.content == 'wechat':

    response= wechat.response_text('^_^')else:

    text=u'text'response= wechat.response_text(text.encode('utf-8') + message.content.encode('utf-8'))elif message.type == 'image':

    response= wechat.response_text('image')elif message.type == 'subscribe':

    response= wechat.response_text('welcome to mywechat!!!')else:

    response= wechat.response_text('unknown'+message.type)

    req.write(response)

    apache.log_error(response)exceptException as e:

    apache.log_error("\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n")

    apache.log_error(str(e))

    apache.log_error("\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n")

    这样简单的demo就Ok了!

    你可以拿起手机给自己的公共账号发消息来测试了!

    tips

    mod_python比较蛋疼的一个地方就是,很多时候出错了它在log里只说一句:Segment Fault.....,根本就没什么用,所以你需要在可能出现异常的地方将它们捕获,并用apache.log_error(str(e))将错误信息输出到log中。

    实际安装过程中,遇到了很多由于expat不兼容而出现的问题,而官方又没有说明,所以我在这上面花了很多时间。实际上centos 5.10系统中预装了expat,但配置Apache安装项时,指定系统的expat的时候总会报错,所以决定自己编译安装expat。mod_python使用过程中,会加载pyexpat.so,而我的系统中pyexpat.so仅支持版本为2.0.1的expat。由于pyexpat.so为python安装包内的内容,我们无法更改,所以我们只能安装版本为2.0.1的expat来解决这个问题。

    使用这种方式实际使用时我还遇到了这个错误“symbol XML_SetHashSalt, version EXPAT_2_0_1_RH not defined in file libexpat.so.1 with link time reference”,通过strings libexpat.so.1.5.2 |grep expat -i我发现我安装的expat中不包含“EXPAT_2_0_1_RH”这个字段,而系统自带的则包括。

    解决方法是

    cd d /usr/local/expat/lib

    ln -s /lib64/libexpat.so.1.5.2 libexpat.so.1.5.2

    这个解决方法很不漂亮,但是目前没找到别的解决办法。

    useful links

    TODO

    文字编码问题还没有解决,当前环境无法给用户发送中文消息

    展开全文
  • laravel-wechat 微信 SDK for Laravel / Lumen, 基于 overtrue/wechat 交流QQ群:319502940 框架要求 overtrue/laravel-wechat:^5.1 -> Laravel/Lumen >= 5.1 overtrue/laravel-wechat:^6.0 -> ...
  • wechat_robot, 微信聊天机器人(个人账号,非订阅号)
  • WeChat SDK

    2019-09-25 22:43:02
    <1>微信SDK及平台搭建 ... 登陆账号 mirrorhanyu@gmail.com  资源中心 中学习如何使用. ...下载WeChat_sample, 导入Eclipse, 在直接运行之前需要设置如下    找到sample里面的debug.keystore...

    <1>微信SDK及平台搭建

      微信开放平台 https://open.weixin.qq.com/

          登陆账号 mirrorhanyu@gmail.com

      资源中心 中学习如何使用.

    <2>下载WeChat_sample, 导入Eclipse, 在直接运行之前需要设置如下

        

      找到sample里面的debug.keystore. 然后运行, 妹的, 运行无效果, 自己写吧~

    <3>发送请求或响应到微信

      首先在微信开放平台的管理中心中, 创建一个移动应用

      在Eclipse中新建一个项目, 并运行一次.

        

      上面的三个框框, 第一个选填. 第三个填ManiActivity包明, 第二个打开从微信开放平台中下载并安装好的 Gen_Signature_Android.apk

          

      提交之后会在7天内审核

        

    转载于:https://www.cnblogs.com/iMirror/p/4181241.html

    展开全文
  • 微信公众号网页开发中,EasyWechat + laravel5.5 auth实现授权注册账号,自动登录 1.准备工作: 安装auth: php artisan make:auth 安装easywechat: composer require "overtrue/laravel-wechat...

    微信公众号网页开发中,EasyWechat + laravel5.5 auth实现授权注册账号,自动登录


    1.准备工作:

    安装auth:

    php artisan make:auth

    安装easywechat:

    composer require "overtrue/laravel-wechat:~4.0"

    创建easywechat配置文件:

    php artisan vendor:publish --provider="Overtrue\LaravelWeChat\ServiceProvider"

    添加wechat.oauth中间件:

    app/Http/Kernel.php中,
    protected $routeMiddleware = [
    'wechat.oauth' => \Overtrue\LaravelWeChat\Middleware\OAuthAuthenticate::class,
    ];

    假设我们的网站域名是www.auth.com

    2.web.php配置路由

    //中间件 mock.user是为了开发时不调用微信授权虚拟的数据,对应的用户是openid为12345的用户,如果不是开发环境需要把这个中间件去掉

    Route::group(['middleware' => 'mock.user'], function () {//这个中间件可以先忽略,我们稍后再说
        Route::middleware('wechat.oauth:snsapi_base')->group(function () {
            Route::get('/login', 'SelfAuthController@autoLogin')->name('login');
        });
        Route::middleware('wechat.oauth:snsapi_userinfo')->group(function () {
            Route::get('/register', 'SelfAuthController@autoRegister')->name('register');
        });
    });
    
    
    Route::get('/', function () {
        return view('welcome');
    });
    
    Route::group(['middleware' => 'auth'], function () {
        Route::get('/example', 'ExampleController@example');
    });

    给login路由配置wechat.oauth:snsapi_base中间件,它是静默获取的,不需要用户授权,并且只会获取用户的openid。
    给register路由配置’wechat.oauth:snsapi_userinfo中间件,它会重定向到微信授权页,需要用户授权,可以获取到用户的nickname,头像等信息。
    给/example路由配置的是auth中间件,如果用户未登陆,它会重定向到命名为login的路由。

    3.mock.user中间件是啥?

    这其实是我们自己创建的一个中间件,可以虚拟一个微信用户,在开发过程中,我们不必真的去请求微信的信息,所有的信息都通过这个中间件来虚拟。

    namespace App\Http\Middleware;
    
    use Closure;
    use Overtrue\Socialite\User as SocialiteUser;
    
    class MockUser
    {
        public function handle($request, Closure $next)
        {
    
            $user = new SocialiteUser([
                'id' => '12345',//openid
                'name' => 'mock',
                'nickname' => 'mock user',
                'avatar' => '',
                'email' => null,
                'original' => [],
                'provider' => 'WeChat',
            ]);
            session(['wechat.oauth_user.default' => $user]);
            return $next($request);
        }
    }
    注册中间件
    protected $routeMiddleware = [
            'mock.user' => \App\Http\Middleware\MockUser::class,
    ];

    4.用户验证的SelfController控制器代码

    <?php
    namespace App\Http\Controllers;
    
    
    use App\User;
    use Illuminate\Support\Carbon;
    use Illuminate\Support\Facades\Auth;
    
    class SelfAuthController extends Controller
    {
        public function getEasyWechatSession()
        {
            $user = session('wechat.oauth_user.default');
            return $user;
        }
    
        public function autoLogin()
        {
            $userInfo = $this->getEasyWechatSession();
            $openId = $userInfo['id'];
            //查看对应的openid是否已被注册
            $userModel = User::where('openid', $openId)->first();
            //如果未注册,跳转到注册
            if (!$userModel) {
                return redirect()->route('register');
            } else {
            //如果已被注册,通过openid进行自动认证,
            //认证通过后重定向回原来的路由,这样就实现了自动登陆。
                if(Auth::attempt(['openid' => $openId, 'password' => ‘123456'])) {
                    return redirect()->intended();
                }
            }
        }
    
        public function autoRegister()
        {
            $userInfo = $this->getEasyWechatSession();
        //根据微信信息注册用户。
            $userData = [
                'password' => bcrypt(’123456'),
                'openid' => $userInfo['id'],
                'nickname' => $userInfo['nickname'],
            ];
            //注意批量写入需要把相应的字段写入User中的$fillable属性数组中
            User::create($userData);
            return redirect()->route('login');
        }
    }

    5.情景再现

    好,假设我们在此网站没有注册过,那么当我们访问www.auth.com/example时,会发生下面事情:

    1).因为/example路由在auth中间件包裹下,所以我们会被重定向到命名为login的路由下,注意命名一词。
    2).因为login路由在wechat.oauth:snsapi_base中间件的包裹下,所以会静默获取用户微信的openid,该信息可以通过session(‘wechat.oauth_user.default’)获取,通过openid查询users表,发现没有此条记录,也就是没有注册过,就会跳转到命名为register的路由下。
    3).因为register路由在wechat.oauth:snsapi_userinfo中间件的包裹下,所以会跳转到微信授权页面,用户授权后,重定向回register,此时可以通过session(‘wechat.oauth_user.default’)获取用户的微信信息,根据微信信息向users表中写入数据,即注册用户。注册成功后重定向到命名为login的路由下。
    4).因为用户已经注册过,所以通过openid可以查询到对应的users表信息,然后使用Auth::attempt([‘openid’ => $openId, ‘password’ => ‘123456’]);对用户进行认证。认证成功后,重定向到我们之前访问的路由www.auth.com/example,在example方法中,我们可以使用Auth::user()获取users表中的信息

    如果我们在此网站注册过,那么当我们访问www.auth.com/example时,如果session没过期,我们可以直接访问,如果session过期,那么会重新走一边login逻辑,register逻辑不会再走。

    参考文献:
    1.easywechat:https://github.com/overtrue/laravel-wechat
    2.laravel5.5手册:https://laravel-china.org/docs/laravel/5.5/authentication#08b509
    3.微信公众号开发手册:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

    展开全文
  • 一、准备微信开发平台账号(需要认证¥300) 二、看代码(注意:其中有自己建的数据表) 1、EasyWeChat 3.0 微信开发平台第三方平台接入 <?php namespace App\Http\Controllers; use Illuminate\Http\Request; ...

    一、准备微信开发平台账号(需要认证¥300)

    二、看代码(注意:其中有自己建的数据表)

    1、EasyWeChat 3.0 微信开发平台第三方平台接入

    <?php
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use EasyWeChat\Foundation\Application;
    use Illuminate\Support\Facades\Redis;
    use DB;
    use App\Models\Wechat\WechatTicket;
    use App\Models\Account;
    
    class OpenWeixinController extends Controller
    {
        protected $options = [
            'open_platform' => [
                'app_id'   => 'xx',
                'secret'   => 'xx',
                'token'    => 'xxx',
                'aes_key'  => 'xxx'
            ],
        ];
    
        public function index(Request $request) {
    
            $this->request = $request;
    
            try{
                $app = new Application($this->options);
                $openPlatform = $app->open_platform; 
                
                // 自定义处理
                $server = $openPlatform->server;
                $server->setMessageHandler(function($event) use($openPlatform){
                    switch ($event->InfoType) {
                        //授权成功
                        case 'authorized':                
                            $res = $openPlatform->getAuthorizationInfo($event->AuthorizationCode);
                            $appid2 = $res->authorization_info['authorizer_appid'];
                            $refresh_token = $res->authorization_info['authorizer_refresh_token'];
    
                            $data = $openPlatform->getAuthorizerInfo($appid2);
    
                            $account = Account::where('appid', $appid2)->first();
                            $info2 = $data['authorizer_info'];
                            $info1 = $data['authorization_info'];
                            if(is_null($account)){
                                $account = Account::create([
                                    'appid' => $info1['authorizer_appid'],
                                    'refresh_token' => $refresh_token,
                                    'name' => $info2['nick_name'],
                                    'head_img' => $info2['head_img'],
                                    'original' => $info2['user_name'],
                                    'com_main_body' => $info2['principal_name'],
                                    'headimg' => $info2['qrcode_url'], //二维码
                                    'status' => 1,
                                    'level' => $this->getLevel($info2),
                                    'type' => 0, 
                                    'token' => random(32),
                                    'encodingaeskey' => random(43)
                                ]);
                            }else{
                                $account->refresh_token = $refresh_token;
                                $account->name =  $info2['nick_name'];
                                $account->type = 0;
                                $account->original = $info2['user_name'];
                                $account->level = $this->getLevel($info2);
                                $account->head_img = $info2['head_img'];
                                $account->save();
                            }
                            break;
                        //取消授权
                        case 'unauthorized':
                            $appid = $event->AuthorizerAppid;
                            $account = Account::where('appid', $appid)->first();
                            if(!is_null($account)){
                                $account->refresh_token = '';
                                $account->save();
                            }
                        //推送component_verify_ticket协议
                        case 'component_verify_ticket':
                            $appid = $event->AppId;         
                            $ticket = $event->ComponentVerifyTicket;
                        
                        	Redis::set($appid . '_component_verify_ticket',$ticket);//存储起来方便后续多台服务器并发调用
                        
                            $wechatTicket = WechatTicket::where('appid', $appid)->orderBy('id')->first();
                            if(is_null($wechatTicket)){
                                $wechatTicket = WechatTicket::create([
                                    'appid' => $appid,
                                    'ticket' => $ticket,
                                    'create_time' => time(),
                                    'update_time' => time()
                                ]);
                            }else{
                               $wechatTicket->ticket = $ticket;
                               $wechatTicket->update_time = time();
                               $wechatTicket->save();
                            }
                    }
                });              
                return $server->serve();
     
            }catch(\Exception $e){
                if(env('APP_DEBUG')){
                    echo $e->getMessage();
                } else {
                     abort(404);
                }
            }
    
    
        }
    
    
        public function auth(Request $request) {
            $app = new Application($this->options);
            $openPlatform = $app->open_platform;
    
            $response = $openPlatform->pre_auth->redirect('http://xxx//index');
            
            //return $response;
            // 获取跳转的链接
            $url = $response->getTargetUrl();
            echo '<a href="'.$url.'">点击第三方授权</a>';
        }
    
    
    }
    

     

    2、EasyWeChat 4.0微信开发平台第三方平台接入

    <?php
    namespace App\Http\Controllers\news;
    
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Cache;
    use Illuminate\Support\Facades\Redis;
    use DB;
    
    use App\Models\Account;
    use App\Models\Wechat\WechatTicket;
    use EasyWeChat\Factory;
    use EasyWeChat\OpenPlatform\Server\Guard;
    
    
    /**
     * 微信开发平台第三方平台接入
     * EasyWeChat 4.0
     */
    class OpenWeixinController extends Controller
    {
        protected $account;
        protected $app;
    
         /**
         * Display a listing of the resource.
         *
         * @return Response
         */
        public function index(Request $request) {
            $this->request = $request;
            try{
                $openPlatform = Factory::openPlatform(config('wechat.open_platform.default'));
    
                // 第三方平台接入处理
                $server = $openPlatform->server;
                // 处理授权成功事件
                $server->push(function ($event) use($openPlatform){
                    //获取(刷新)授权公众号或小程序的接口调用凭据(令牌)              
                    $res = $openPlatform->handleAuthorize($event->AuthorizationCode);
                    $appid2 = $res->authorization_info['authorizer_appid'];
                    $refresh_token = $res->authorization_info['authorizer_refresh_token'];
    
                    //获取授权方的帐号基本信息
                    $data = $openPlatform->getAuthorizer($appid2);
                    $account = Account::where('appid', $appid2)->first();
                    $info2 = $data['authorizer_info'];
                    $info1 = $data['authorization_info'];
                    if(is_null($account)){
                        $account = Account::create([
                            'appid' => $info1['authorizer_appid'],
                            'refresh_token' => $refresh_token,
                            'name' => $info2['nick_name'],
                            'head_img' => $info2['head_img'],
                            'original' => $info2['user_name'],
                            'com_main_body' => $info2['principal_name'],
                            'headimg' => $info2['qrcode_url'], //二维码
                            'status' => 1,
                            'level' => $this->getLevel($info2),
                            'type' => 0, 
                            'token' => random(32),
                            'encodingaeskey' => random(43)
                        ]);
                    }else{
                        $account->refresh_token = $refresh_token;
                        $account->name =  $info2['nick_name'];
                        $account->type = 0;
                        $account->original = $info2['user_name'];
                        $account->level = $this->getLevel($info2);
                        $account->head_img = $info2['head_img'];
                        $account->save();
                    }
                }, Guard::EVENT_AUTHORIZED);
    
    
                // 处理授权更新事件
                $server->push(function ($event) use($openPlatform){
                    
                }, Guard::EVENT_UPDATE_AUTHORIZED);
    
                // 处理授权取消事件
                $server->push(function ($event) {
                    $appid = $event->AuthorizerAppid;
                    $account = Account::where('appid', $appid)->first();
                    if(!is_null($account)){
                        $account->refresh_token = '';
                        $account->save();
                    }
                }, Guard::EVENT_UNAUTHORIZED);
    
                //VerifyTicket component_verify_ticket协议推送
                $server->push(function ($event) use($openPlatform){
                    $appid = $event->AppId;         
                    $ticket = $event->ComponentVerifyTicket;
                    
                    //保存component_verify_ticket协议
                    Redis::set($appid . '_component_verify_ticket', $ticket);//存储起来方便后续多台服务器并发调用
                
                    $wechatTicket = WechatTicket::where('appid', $appid)->orderBy('id')->first();
                    if(is_null($wechatTicket)){
                        $wechatTicket = WechatTicket::create([
                            'appid' => $appid,
                            'ticket' => $ticket,
                            'create_time' => time(),
                            'update_time' => time()
                        ]);
                    }else{
                        $wechatTicket->ticket = $ticket;
                        $wechatTicket->update_time = time();
                        $wechatTicket->save();
                    }
                }, Guard::EVENT_COMPONENT_VERIFY_TICKET);
                 
                return $server->serve();
                
            }catch(\Exception $e){
                if(env('APP_DEBUG')){
                    echo $e->getMessage();
                } else {
                     abort(404);
                }
            }
    
        }
    
        public function auth(Request $request) {
            try{      
                $openPlatform = Factory::openPlatform(config('wechat.open_platform.default'));
                // 获取跳转的链接
                $url = $openPlatform->getPreAuthorizationUrl('url');
                // 获取跳转的链接
                echo '<a href="'.$url.'">点击第三方授权</a>';
            }catch(\Exception $e){
                //echo $e->getMessage();
                $url = '';
            }
            //return view('admin.auth.note', compact('url'));
        }
    
        public function callback(Request $request) {
            $filter =  $request->all();
            //return redirect()->to(site_path('account/wechat', 'admin'))->with('message', '第三方接入成功!');
            return redirect()->to('url')->with('message', '第三方接入成功!');
        }
    
        // 公众号分组
        public function getLevel($info = array()){
            $level = 0;
            if(!empty($info['MiniProgramInfo'])){
                $level = 5;
            }else if($info['service_type_info']['id'] == 0 || $info['service_type_info']['id'] == 1){
                //订阅号
                if($info['verify_type_info']['id'] >= 0){
                    //已认证
                    $level = 3;
                }else{
                    $level = 1;
                }
            }else if($info['service_type_info']['id'] == 2){
                //服务号
                if($info['verify_type_info']['id'] >= 0){
                    //已认证
                    $level = 4;
                }else{
                    $level = 2;
                }
            }
            return $level;
        }
    
    
    }
    

    调用auth函数进行第三方授权

    3、自定义推送component_verify_ticket协议

        EasyWeChat自动缓存了component_verify_ticket。

        想在不同的服务器将进行操作,必须将component_verify_ticket保存到数据库(Redis,Mysql)。

        看下面的代码:EasyWeChat4.0

                $openPlatform = Factory::openPlatform(config('wechat.open_platform.default'));  
                $verify_ticket = $openPlatform->verify_ticket;
                //重设第三方平台verify_ticket 方便多台机器用
                $app_id = $openPlatform->config->app_id;
                
                //Redis
                $ticketCache = Redis::get($app_id . '_component_verify_ticket');
                
                if(is_null($ticketCache) || empty($ticketCache)){
                    //mysql
                    $wechatTicket = WechatTicket::where('appid', $app_id)->orderBy('id')->first();
                    if(!is_null($wechatTicket)){
                        $ticketCache = $wechatTicket->ticket;
                    }
                }
                
                if($ticketCache){
                    $verify_ticket->setTicket($ticketCache);
                } 
                
                //代公众号实现业务
                $app = $openPlatform->officialAccount($account->appid, $account->refresh_token);
    
                //代小程序实现业务
                //$app = $openPlatform->miniProgram($account->appid, $account->refresh_token);
    

    三、问题

    1、在授权URL测试的时候,如果报AesException: 签名验证错误,可能是代码你参数填写有错。一定要注意是填写第三方平台的信息,不是公众号的信息。

    2、在授权URL测试的时候,如果报Illegal key size,那么就是指密钥长度是受限制的,java运行时环境读到的是受限的policy文件。去掉这种限制需要下载Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files(https://yunpan.cn/cSrtk3Fk6WgAs  访问密码 244a)。替换${java_home}/jre/lib/security/ 下面的local_policy.jar和US_export_policy.jar(jdk,jre最好都替换。)。注意一定要重启TOMCAT才能生效。

    3、component ticket is exprie ticket过期,每10分钟会微信服务器会推送到授权事件的URL中。这里可以不用处理设置过期时间(因为这里的ticket是无接口调用权限的,而且是微信服务器自己推送的)

    4、注意公众号消息处理的URL必须加上$APPID$

    5、component_access_token过期时间为2个小时,和公众号的Token一样(我处理的是存储过期时间,超过就请求。而不是定时刷新)

    6、可以选择你自己需要第三方托管的权限集,比如你其他消息只走微信公众号,只有客服消息走第三方平台。

    7、异常:请确认授权入口页所在域名,与授权后回调页所在域名相同,并且,此两者都必须与申请第三方平台时填写的授权发起页域名相同。授权入口页所在域名:空

     

    (改地址不能直接方法,需要<a href="授权地址"></a>标签进行跳转)

       当配置正常,<a href="授权地址"></a>不能正常访问时,可以试试以下

       第一种方式:<meta name="referrer" content="never">

       第二种方式:<meta http-equiv="refresh" content="0; url=授权地址"> 重定向

    8、有可能会出现你每次启动项目的时候,由于每10分钟才会验证一次Ticket,那么直接调用接口,如果服务器还没推送,会出现ticket失效(不过在正式环境还好)(就算全网通过后也会推送component_verify_ticket协议)。

    9、每次授权后,想要获取最新的权限必须重新扫码授权。否则无法获取最新的消息。

    10、获取令牌的官网接口

    11、第三方中的授权的URL一级接收公众号消息的URL都只能在同一个一级域名下

    12、如果是并发量大,做集群的话,一定要把所有服务器的ip都加到白名单中

    展开全文
  • linux+apache+mod_python+wechat_sdk搭建微信公共账号服务器 转载请注明本文原作者:FignerLiu PRE 最近尝试了下使用python搭建微信公共账号服务器,实现了简单的消息收发功能。其中遇到了很多问题,特此记录下来...
  • wechat.rar

    2020-04-09 08:55:04
    根据微信公众平台接口文档简单得不能再简单的...要测试本范例,需要一个微信公众账号,一个有公网IP的服务器,本范例自带web服务器,所以请先停掉服务器上已有的web服务再运行。 本范例在Delphi XE4 Update1上开发。
  • 解决方案多个账号同时爬取 test_WechatUrls.py 登录微信PC端获取文章信息 test_WechatInfo.py 快速获取大量文章urls(利用历史文章获取链接) test_GetUrls.py 利用公众号获取链接,并获取阅读点赞 test_...
  • 我也已经不更新了,所以不用给我发邮件问我如何解决了]An Open Source Java SDK for WeChat Open PlatformWeChat4j 是为腾讯微信公众平台制作的一个Java版本的SDK,旨在快速建立开发模式的微信公众账号。目前WeChat4...
  • Android wechat 支付

    2018-09-17 15:13:00
    wechat 官方接入文档 App内支付 可以参照 Android 微信支付详解与Demo ​ 源码下载 主要流程: 1.1 微信支付平台注册账号 ​ 注:注册并申请成功以后,需要在API安全中设置你的API密钥 32个字符。建议使用 MD5...
  • 个人账号是可以申请此类接口权限的. 当小程序账号注册完成以及申请实时音视频流权限之后. 获取appid 并使用微信开发者工具导入项目, 选择 client 文件夹, 然后点击 真机调试, 使用手机微信调试RTMP视频流. 记住要先...
  • 微信公众号结合着内置浏览器,有着普通浏览器无法完成的服务,前者可以获取浏览页面的微信用户的...注册微信公众平台并申请公众平台测试账号填写接口配置信息服务器与公众号验证Token项目引入weixin-java-mp一、注册...
  • Java Wechat Pay Project

    千次阅读 2019-10-26 20:32:01
    Java Wechat Pay Project ZJ 视频课程项目之微信支付系统——整个项目的完整生命周期。 开发流程——数据库设计——接口设计——开发、编码、部署功能到阿里云服务器、域名备案、解析到服务器、通过域名进行访问。 ...
  • wechat API地址

    2017-12-07 11:00:16
    1. 微信硬件设备开发文档:http://iot.weixin.qq.com/index.html 2. 微信-蓝牙开发demo: ... 3.申请微信公众平台接口测试账号: http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login 4. 微信公...
  • wechat实现微信聊天机器人

    万次阅读 2019-03-23 02:50:43
    首先要在图灵机器人的网站注册个账号获得一个图灵账号每个账号可以创建几个机器人,然后可以获得key和userid填入下面,运行这个程序就可以测试你的图灵机器人了。接着我们可以用wechat这个网页版的微信库来接收和...
  • 第一步:要去:https://open.weixin.qq.com(微信开发平台)注册账号并且创建一个移动应用。创建应用的时候需要填写Bundle ID(ios)和包名(安卓)Bundle ID在哪里?原文:...
  • 更新: 测试号,请使用 JFinal_weixin ,因为微信提供API不同(导致我不能使用snsapi_userinfo)。 ...openid 只和你的微信号和服务号(订阅号)有关,即在同一个订阅号下是唯一的 ..."wechat.html" ); } }
  • Ubuntu18安装Wechat(转载)

    2019-11-12 20:04:19
    此方法的优点在于使用Electronic Wechat (是类似于Wechat的开源替代,因为Wechat无Linux版本)代替开浏览器登录网页版,所以局限性还是很大的。 1. Open terminal via Ctrl+Alt+T or by searching it from app ...
  • WeChat applet VS Mobile app

    2019-01-22 13:17:46
    WeChat applet VS Mobile app 微信小程序 VS 手机应用程序 简介 绘制一张表格,体现微信小程序与手机应用之间的区别,用处是如果想起,可以拿出来看一看,在做项目选型时作为参考。 比较点 微信小程序 手机应用 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 392
精华内容 156
关键字:

wechat账号