php百度小程序的联合登录/手机号授权登录

开发流程:

1.在button 组件中,将 open-type 设置为 getPhoneNumber,并使用 bindgetphonenumber 作为获取用户手机号的回调

2.返回值中的 encryptedData 和 iv 需要发送到服务端解密,详细可参考用户数据的签名验证和加解密,代码处理包括:

  • 获取session_key
  • 解密

操作流程:

(1)获取session_key:参考文档:https://smartprogram.baidu.com/docs/develop/api/open/log_Session-Key。code由前端传值。

<?php
/**
 * 获取sessionkey 方法
 * @param string $code        由swan.login获取的临时登录凭证
 * @param string $clientId    小程序appkey
 * @param string $sk          小程序appSecretKey
 */
function reqGetSessionkey($code, $clientId, $sk)
{
    $url = 'https://spapi.baidu.com/oauth/jscode2sessionkey';
    $data = array(
        "code" => $code,
        "client_id" => $clientId,
        "sk" => $sk
    );
    $ret = curlPost($url, $data);
    
    return $ret;
}

/**
 * curl POST请求工具类
 *
 * @param string $url
 *            请求的url地址
 * @param array $postDataArr
 *            传递的数组参数
 * @return string 检测结果json字符串
 */
function curlPost($url, $postDataArr)
{
    $headerArr = array(
        "Content-type:application/x-www-form-urlencoded"
    );
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $postDataArr);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headerArr);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($curl);
    curl_close($curl);
    
    return $output;
}

// 获取sessionkey demo
echo reqGetSessionkey("8ba01454ac57775d3692f5dbfcac7a28NW", "4fecoAqgCIUtzIyA4FAPgoyrc4oUc25c", "xxx");

返回:

{
    openid: "l214zFqNrEuIEnp6m7Y01sw8yj",
    session_key: "981ce8b151c0599acf7ad1a673c6ff5e"
}

(2)解密:参考文档:https://smartprogram.baidu.com/docs/develop/api/open/log_userdata。sessio_key,由后端自己获取。iv 和 ciphertext(前端变量名为encryptedData) 由前端传值。

<?php
/**
 * @Author: smartprogram_rd@baidu.com
 * Copyright 2018 The BAIDU. All rights reserved.
 *
 * 百度小程序用户信息加解密示例代码(面向过程版)
 * 示例代码未做异常判断,请勿用于生产环境
 */
function test() {
    $app_key = 'y2dTfnWfkx2OXttMEMWlGHoB1KzMogm7';
    $session_key = '1df09d0a1677dd72b8325aec59576e0c';
    $iv = "1df09d0a1677dd72b8325Q==";
    $ciphertext = "OpCoJgs7RrVgaMNDixIvaCIyV2SFDBNLivgkVqtzq2GC10egsn+PKmQ/+5q+chT8xzldLUog2haTItyIkKyvzvmXonBQLIMeq54axAu9c3KG8IhpFD6+ymHocmx07ZKi7eED3t0KyIxJgRNSDkFk5RV1ZP2mSWa7ZgCXXcAbP0RsiUcvhcJfrSwlpsm0E1YJzKpYy429xrEEGvK+gfL+Cw==";
    $plaintext = decrypt($ciphertext, $iv, $app_key, $session_key);
    // 解密结果应该是 '{"openid":"open_id","nickname":"baidu_user","headimgurl":"url of image","sex":1}'
    echo $plaintext, PHP_EOL;//PHP_EOL php换行输出
}
test();

/**
 * 数据解密:低版本使用mcrypt库(PHP < 5.3.0),高版本使用openssl库(PHP >= 5.3.0)。
 *
 * @param string $ciphertext    待解密数据,返回的内容中的data字段
 * @param string $iv            加密向量,返回的内容中的iv字段
 * @param string $app_key       创建小程序时生成的app_key
 * @param string $session_key   登录的code换得的
 * @return string | false
 */
function decrypt($ciphertext, $iv, $app_key, $session_key) {
    $session_key = base64_decode($session_key);
    $iv = base64_decode($iv);
    $ciphertext = base64_decode($ciphertext);

    $plaintext = false;
    if (function_exists("openssl_decrypt")) {
        $plaintext = openssl_decrypt($ciphertext, "AES-192-CBC", $session_key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
    } else {
        $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, null, MCRYPT_MODE_CBC, null);
        mcrypt_generic_init($td, $session_key, $iv);
        $plaintext = mdecrypt_generic($td, $ciphertext);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
    }
    if ($plaintext == false) {
        return false;
    }

    // trim pkcs#7 padding
    $pad = ord(substr($plaintext, -1));
    $pad = ($pad < 1 || $pad > 32) ? 0 : $pad;
    $plaintext = substr($plaintext, 0, strlen($plaintext) - $pad);

    // trim header
    $plaintext = substr($plaintext, 16);
    // get content length
    $unpack = unpack("Nlen/", substr($plaintext, 0, 4));
    // get content
    $content = substr($plaintext, 4, $unpack['len']);
    // get app_key
    $app_key_decode = substr($plaintext, $unpack['len'] + 4);

    return $app_key == $app_key_decode ? $content : false;
}

Notice:
1、session_key是具有时效性的,过期的 session_key 将无法使用。开发者在 session_key 失效时,需要通过重新执行登录流程获取有效的 session_key 。无需缓存session_key

2、 使用checkSession()可以校验 Session Key 是否有效,从而避免小程序反复执行登录流程,参考授权流程图中 checkSession() 使用。

3、 智能小程序不会把 session_key 的有效期告知开发者。我们会根据用户使用小程序的行为对 session_key 进行续期。用户越频繁使用小程序, session_key 有效期越长。

4、session_key 过期会导致开放数据解密失败。要判断当前用户的授权会话是否仍处于有效期,可调用swan.checkSession()方法进行判断,详情参照授权登录流程说明。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在PHP中实现微信小程序授权获取用户信息并绑定手机号登录,可以按照以下步骤进行操作: 1. 在微信小程序端,通过`wx.login`获取到用户的临时登录凭证`code`。 2. 将获取到的`code`发送到服务器端,使用`https`接口调用`code2Session`接口,获取到`openid`和`session_key`。 3. 将`openid`和`session_key`保存至服务器端数据库或缓存中。 4. 在小程序端,使用`wx.getUserInfo`获取用户信息,包括`nickName`、`avatarUrl`等,并将用户信息传输到服务器端。 5. 在服务器端,接收到用户信息后,将用户信息保存到服务器数据库中,可以使用`openid`作为用户的唯一标识。 6. 在小程序端,点击绑定手机号的按钮,调用`wx.request`向服务器发送请求,请求获取手机号的能力。 7. 在服务器端,接收到手机号请求后,可以返回一个包含手机号获取能力的`code`给小程序端。 8. 小程序端收到`code`后,调用`wx.request`向服务器发送请求,请求获取手机号。 9. 服务器端接收到获取手机号的请求后,可以通过调用微信开放平台提供的解密能力,解密包含手机号的数据,并将解密得到的手机号与用户信息进行绑定。 10. 绑定成功后,返回相应的状态给小程序端。 总结:通过以上步骤,我们可以在PHP中实现微信小程序授权获取用户信息并绑定手机号登录的功能。在小程序端,用户使用微信授权登录后,将用户信息传输到服务器端保存,并通过绑定手机号使用户能够更便捷地登录和使用小程序。同时,在服务器端需要进行数据加密和解密的操作,确保用户的信息安全。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值