微信开发 - 多平台网页授权怎么做?

相信从事微信开发的小伙伴们遇到过这样的情况,就是甲方的微信公众帐号的网页授权指定域名指向了其它的域名(以后叫A),并在该域名下实现了一部分功能。现在,需要开发另一个功能,且该功能所在的域名(以后叫B)不再网页授权指定域名下。 怎么办呢?造成网页授权域名的冲突了。

解决方案:
需要获取用户信息的时候我们完全可以让用户跳转到A方完成授权,授权完成后带着关键参数回传给B。然后B获取关键参数,请求微信生成用户相关信息。
思路有了,怎么实现呢?

1、首先,我们需要A给我们提供一个接口,该接口的调用必须要2个参数

@param String token 签名机制,目的防止用户授权泄漏,被其它人调用了这个接口。
@param String retUrl 回调地址,完成授权后让用户post回跳到这个地址(retUrl 最好做一个urlencode转义),当然post中也包含着一些关键的数据(code)

2、用户回传的code 数据后,我们可以根据这个code 获得用户的数据了(详情见微信网页授权,也就是通过code 获取临时授权签名 access_token 在通过access_token 获得 用户信息)

是不是很简单,现在我演示一下demo。

为方便时间我用php代码做演示。
A、B都需要依赖的类auth.php

<?php
class Wxuserapi {
    /*以下内容请填写*/
    private $app_id = '';      
    private $app_secret = '';

    /*配置信息*/
    public function __construct($appid,$appsecret){
        $this->app_id = $appid;
        $this->app_secret = $appsecret;
    }
    /**
     * 获取微信授权链接
     * 
     * @param string $redirect_uri 跳转地址
     * @param mixed $state 参数
     */
    public function get_authorize_url($redirect_uri = '', $state = '')
    {
        $redirect_uri = urlencode($redirect_uri);
        $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->app_id}&redirect_uri={$redirect_uri}&response_type=code&scope=snsapi_userinfo&state={$state}#wechat_redirect";  
        echo "<script language='javascript' type='text/javascript'>";  
        echo "window.location.href='$url'";  
        echo "</script>";       
    }       

    /**
     * 获取授权token
     * 
     * @param string $code 通过get_authorize_url获取到的code
     */
    public function get_access_token($code = '')
    {
        $token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->app_id}&secret={$this->app_secret}&code={$code}&grant_type=authorization_code";
        $token_data = $this->http($token_url);
        if(!empty($token_data[0]))
        {
            return json_decode($token_data[0], TRUE);
        }

        return FALSE;
    }   

    /**
     * 获取授权后的微信用户信息
     * 
     * @param string $access_token
     * @param string $open_id
     */
    public function get_user_info($access_token = '', $open_id = '')
    {
        if($access_token && $open_id)
        {
            $access_url = "https://api.weixin.qq.com/sns/auth?access_token={$access_token}&openid={$open_id}";
            $access_data = $this->http($access_url);
            $access_info = json_decode($access_data[0], TRUE);
            if($access_info['errmsg']!='ok'){
                exit('页面过期');
            }
            $info_url = "https://api.weixin.qq.com/sns/userinfo?access_token={$access_token}&openid={$open_id}&lang=zh_CN";
            $info_data = $this->http($info_url);       
            if(!empty($info_data[0]))
            {
                return json_decode($info_data[0], TRUE);
            }
        }

        return FALSE;
    }       
    /**
     * Http方法
     * 
     */ 
    public function http($url)
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_HEADER, false);
        $output = curl_exec($ch);//输出内容
        curl_close($ch);
        return array($output);
    }
}
?>

A、B 需要依赖的函数库 common.php

/**
 * 获取当前完整url
 * @return
 * String 当前地址
 */
function getMyUrl()
{
    if($_SERVER['QUERY_STRING'])
    {
        return 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'];
    }else{
        return 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
    }
}


/***token 签名机制 我不写,每个人都有自己的算法,我就不献丑了***/
/**
 * token 签名生成
 * @return
 * String token
 */
function getToken()
{

}

/**
 * token 验证
 * @param
 * String token 需要验证的token
 * @return
 * boolean
 */
 function checkToken($token)
 {

 }

域名A 要做的工作

<?php
session_start();
require("./auth.php");
require("./common.php");
if(isset($_GET['urlcode']))
{
    $_SESSION['urlcode'] = $_GET['urlcode'];

    //token 验证机制
    if(isset($_GET['token']))
    {
        if(!checkToken(trim($_GET['token'])))
        {
            //签名错误处理
            header("content-type:text/html;charset=utf-8");
            echo "token error";
            exit;
        }
    }
}

//必填项,参数可以在微信后台中找到
$config = array(
    'appid'         =>    '',     //公众号appid
    'appsecret'     =>    ''      //公众号appsecret
);

$auth = new \Wxuserapi($config['appid'],$config['appsecret']);
if(isset($_GET['code'])){
    $code 		= $_GET['code'];
}else{
    $url = getMyUrl();
    $auth->get_authorize_url($url,"snsapi_userinfo");
    exit;
}
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
    </head>
    <body>
        <form action="<?php echo urldecode($_SESSION['urlcode']); ?>" name="form1" method="post">
            <input type="hidden" name="code" value="<?php echo $code; ?>" />
        </form>
    </body>
    <script>
        window.onload = function(){
            document.form1.submit();
        }
    </script>
</html>

域名B 要做的工作

<?php
session_start();
require("./auth.php");
require("./common.php");

$code = isset($_POST['code']) ? $_POST['code'] : false;

//不存在code 时回调到域名A 指定接口地址
if(!$code)
{
    $retUrl = urlencode(getMyUrl());
    $token  = getToken();
    //假设我们域名A 提供的接口地址是  http://www.xxx.com/auth.php
    $url = "http://www.xxx.com/auth.php?urlcode={$retUrl}&token={$token}";

    header("location:{$url}");
    exit;
}

//必填项,参数可以在微信后台中找到
$config = array(
    'appid'         =>    '',     //公众号appid
    'appsecret'     =>    ''      //公众号appsecret
);

$auth = new \Wxuserapi($config['appid'],$config['appsecret']);
$access		= $auth->get_access_token($code);
$userinfo 	= $auth->get_user_info($access['access_token'],$access['openid']);

var_dump($userinfo);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值