小程序基础开发(三):授权,获取用户信息,注册,登录,简单封装request请求

一,授权

1,首先在app.js里检测用户是否授权

// 查看是否授权
    wx.getSetting({
      success: function (res) {
        if (res.authSetting['scope.userInfo']) {
          console.log('用户已授权' + res.authSetting['scope.userInfo']);
        } 
        else {
          console.log('用户未授权');
          wx.navigateTo({
            url: '../login/login'
          })
        }
      }
    })

2,没有授权就跳到授权页(单独一个页面,需要点击open-type="getUserInfo"的按钮)

<button class="cu-btn round shadow-blur lg bg-{{Theme}}" open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="bindGetUserInfo">授权登录</button>

3,拒绝授权或者授权失败,就让用户停留在授权页,成功则跳到首页

bindGetUserInfo: function (e) {
    if (e.detail.userInfo) {
      //用户按了允许授权按钮
      console.log('用户按了允许授权按钮');
      var that = this;
      wx.navigateTo({     
        url: '../index/index'
      })
    } else {
      //用户按了拒绝按钮
      wx.showModal({
        title: '警告',
        content: '您点击了拒绝授权,将无法进入小程序,请授权之后再进入!!!',
        showCancel: false,
        confirmText: '返回授权',
        success: function (res) {
          if (res.confirm) {
            console.log('用户点击了“返回授权”')
          }
        }
      })
    }
  },

二,获取用户信息

1,获取openid,用户名,头像等等
在点击授权后,获取用户的信息,包括openid和unionid等等,发送给后台注册

wx: wx.getUserInfo({
        withCredentials: true,//开启获取私密信息
        success: function (res) {
          //console.log('获取成功:' + JSON.stringify(res))
          var UserInfo = JSON.stringify(res);//放入 data{},post数据的key就是UserInfo
		  //发送加密数据UserInfo
          })
        },
        fail: function (res) {
          console.log('获取unionid失败(组件失败)');
        },
      })

2,获取手机号
官方文档说明:

获取微信用户绑定的手机号,需先调用wx.login接口。 因为需要用户主动触发才能发起获取手机号接口,所以该功能不由 API
来调用,需用 button 组件的点击来触发。
注意:目前该接口针对非个人开发者,且完成了认证的小程序开放(不包含海外主体)。需谨慎使用,若用户举报较多或被发现在不必要场景下使用,微信有权永久回收该小程序的该接口权限。
使用方法 需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过
bindgetphonenumber 事件回调获取到微信服务器返回的加密数据, 然后在第三方服务端结合 session_key 以及
app_id 进行解密获取手机号。 代码示例 Page({ getPhoneNumber
(e) {
console.log(e.detail.errMsg)
console.log(e.detail.iv)
console.log(e.detail.encryptedData) } }) encryptedData String 包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法
iv String 加密算法的初始向量,详细见加密数据解密算法 cloudID string 敏感数据对应的云
ID,开通云开发的小程序才会返回,可通过云调用直接获取开放数据,详细见云调用直接获取开放数据

三,注册

主要是数据库录入openid,其他可看情况获取,例如unionID,用户名,头像,手机等等
1,首先是post加密数据,放个获取到的UserInfo例子

{“errMsg”:“getUserInfo:ok”,“rawData”:"{“nickName”:“R”,“gender”:1,“language”:“zh_CN”,“city”:"",“province”:“Bronkhorstspruit”,“country”:“South
Africa”,“avatarUrl”:“https://wx.qlogo.cn/mmopen/vi_32/DQHC3FoaN1TYicamwQaCPANedQBJj9DbNRy5BXeBEglTSJJfA/132”}",“userInfo”:{“nickName”:“R”,“gender”:1,“language”:“zh_CN”,“city”:"",“province”:“Bronkhorstspruit”,“country”:“South
Africa”,“avatarUrl”:“https://wx.qlogo.cn/mmopen/vi_32/DQHC3FoaN1TYicaoQBJj9DbNRy5BXeBEglTSJJfA/132”},“signature”:“ad4a2f5834d1eb9774503f90”,“encryptedData”:“oiWQJPHfxXBszs0HcpwnEuztq8jYbMWvu9AUir/QdSGvgW7HxGgXc0zAkPPTweCmTto0la+nCl5qgw5EUPYwltIrNEDTQolPDzny4ySKT2u1YFaRtzimfg37g+9Ho0q3gsPBy44ApaLdqeBvMLVit/JwJViPxLuEUwtkNUOuyccZGkrIx4pAQpLuE0bGsuSjceMcX8kf2CM7PfM4EFRANL3Zq3UyXSRV+hHgk4kXZ6KE7pjf9IuzA3iURqQ9nYHJR2wmFCSOvjt6G0Hn2vesg9EX1/4/PAY0jryvuxoKh12fYL59lw7chybRqGrn2b1uLnrxUI7htQBVLGwrtJvs+rrd0FX1PBF1sjSQ26/X8pXA43w+k1o1fFoRElw26vipdq3OTp9iIro=”,“iv”:“sWy22akgYteA==”}

2,解密开发数据
官方说明文档解密开发数据
官方有各种后台语言的示例代码,贴一个PHP的例子

<?php

/**
 * 对微信小程序用户加密数据的解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */


include_once "errorCode.php";


class WXBizDataCrypt
{
  private $appid;
	private $sessionKey;

	/**
	 * 构造函数
	 * @param $sessionKey string 用户在小程序登录后获取的会话密钥
	 * @param $appid string 小程序的appid
	 */
	public function __construct( $appid, $sessionKey)
	{
		$this->sessionKey = $sessionKey;
		$this->appid = $appid;
	}


	/**
	 * 检验数据的真实性,并且获取解密后的明文.
	 * @param $encryptedData string 加密的用户数据
	 * @param $iv string 与用户数据一同返回的初始向量
	 * @param $data string 解密后的原文
     *
	 * @return int 成功0,失败返回对应的错误码
	 */
	public function decryptData( $encryptedData, $iv, &$data )
	{
		if (strlen($this->sessionKey) != 24) {
			return ErrorCode::$IllegalAesKey;
		}
		$aesKey=base64_decode($this->sessionKey);

        
		if (strlen($iv) != 24) {
			return ErrorCode::$IllegalIv;
		}
		$aesIV=base64_decode($iv);

		$aesCipher=base64_decode($encryptedData);

		$result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);

		$dataObj=json_decode( $result );
		if( $dataObj  == NULL )
		{
			return ErrorCode::$IllegalBuffer;
		}
		if( $dataObj->watermark->appid != $this->appid )
		{
			return ErrorCode::$IllegalBuffer;
		}
		$data = $result;
		return ErrorCode::$OK;
	}

}
<?php

/**
 * error code 说明.
 * <ul>

 *    <li>-41001: encodingAesKey 非法</li>
 *    <li>-41003: aes 解密失败</li>
 *    <li>-41004: 解密后得到的buffer非法</li>
 *    <li>-41005: base64加密失败</li>
 *    <li>-41016: base64解密失败</li>
 * </ul>
 */
class ErrorCode
{
	public static $OK = 0;
	public static $IllegalAesKey = -41001;
	public static $IllegalIv = -41002;
	public static $IllegalBuffer = -41003;
	public static $DecodeBase64Error = -41004;
}

?>

解密后

{
    "openId": "OPENID",
    "nickName": "NICKNAME",
    "gender": GENDER,
    "city": "CITY",
    "province": "PROVINCE",
    "country": "COUNTRY",
    "avatarUrl": "AVATARURL",
    "unionId": "UNIONID",
    "watermark":
    {
        "appid":"APPID",
        "timestamp":TIMESTAMP
    }
}
{
    "phoneNumber": "13580006666",
    "purePhoneNumber": "13580006666",
    "countryCode": "86",
    "watermark":
    {
        "appid":"APPID",
        "timestamp": TIMESTAMP
    }
}

四,登录

官方说明文档:登录

function postCode() {
  return new Promise(function (resolve) {
    wx.login({
      success: function (res) {
        //console.log('code=' + res.code)
        //发送请求
        wx: wx.request({
          url: 'login.php',
          data: { code: res.code },
          header: { 'content-type': 'application/x-www-form-urlencoded' },
          method: 'POST',
          dataType: 'json',
          responseType: 'text',
          success: function (res) {
              console.log('登录成功返回:' + res + JSON.stringify(res))
              wx.setStorageSync('sid', res.data.msg)//把返回的(自定义登录凭证=> sessionId\token) 存入本地
              var newsid = res.data.msg;
              resolve(newsid); //Promise成功后回调参数,相当于return。
          },
          fail: function (res) {
            wx.showModal({
              title: '温馨提示',
              content: res.data.error || '网络繁忙,请稍后重试!',
              showCancel: false,//关闭取消按钮
            })
           },
          complete: function (res) { },
        })
      }
    })
  })
}
//api接口
$api = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$secret}&js_code={$code}&grant_type=authorization_code";
//获取GET请求
function httpGet($url){
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_TIMEOUT, 500);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
    curl_setopt($curl, CURLOPT_URL, $url);
    $res = curl_exec($curl);
    curl_close($curl);
    if($res=='')
    	httpGet($url);
    
    $str=json_decode($res);
    //print_r($str);
    return $str;
}
if($code!='')
{
	$wxloginSttr=httpGet($api);//发送取得用户信息
	$openid = $wxloginSttr->openid;//发送取得openid
	if($openid!='')
	{
		$onlycode='';//自定义加密,生成唯一session标识,返回给微信
		$sql="";//检查用户是否存在
		$sl=$db->query($sql);
		$sl2=$sl->fetch();

		////删除用户之前的session
		unset($data);
		$mdb->delete('wx_session',$data,0);
		
		//录入登录session
		unset($data);
		$data["_id"]=$onlycode;
		$data['session_key']=$wxloginSttr->session_key;
		$data['syws_time']=time()+86400;//登陆有效期24小时
		$data3=$mdb->insert('wx_session',$data);
		
		if($data3==1)//insert==ok
		{
			$msg["msg"]=$onlycode;
		}else
		{
			$msg["error"]="请重新登录!!!!";
		}

	}else
	{
		$msg["error"]="请重新登录!!!!!";
	}
}else
{
	$msg["error"]="非法登录!";
}
echo json_encode($msg);

五,封装request请求

官方说明文档:request组件
header 中不能设置 Referer。
content-type 默认为 application/json

data 参数说明
最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String 。转换规则如下:

对于 GET 方法的数据,会将数据转换成 query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)…)
对于 POST 方法且 header[‘content-type’] 为 application/json 的数据,会对数据进行 JSON 序列化
对于 POST 方法且 header[‘content-type’] 为 application/x-www-form-urlencoded 的数据,会将数据转换成 query string (encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)…)

目前自己用的封装比较简单,有基础功能,但还需不断完善改进。

/* 封装request-请求服务器
**含**传递和重获session,统一处理session异常
**不含**拦截器和单独处理其他异常
const util = require('../../utils/util.js')
 util.requestUrl({
      url: "接口路径",
      data:{},
      method:"post",
      success:function(res){
        console.log(res)
      },
      header:'请求头,可不填'
    })
*/
function requestUrl({ url, data, method, success, header}) {
  wx.showLoading({
    title: '加载中',
  })
  let server = app.globalData.reURL;//正式域名
  //请求头可根据实际情况填写
  let header_type = header || { 'content-type': 'application/x-www-form-urlencoded', Authorization: wx.getStorageSync("sid") };
  wx.request({
    url: server + url,
    data: data,
    header: header_type,
    method: method,
    dataType: 'json',
    responseType: 'text',
    success: (res) => {
      console.log(res.data);
      if (登录session==OK) {
        wx.hideLoading();// 隐藏加载框
        success(res)
      }
      else if (登录session过期) {
        //重新登录
        postCode().then(function (locationData) {
          console.log('重新获取的new-session-id:' + locationData)
          //重新执行
          requestUrl({
            url,
            data,
            method,
            success,
            header
          })
        })
      }
      else {
        wx.hideLoading();
        //其他状态判为非法入侵,函数回馈提示后截断在当页
        wx.showModal({
          title: '温馨提示',
          content: res.data.error || '网络繁忙,请稍后重试!',
          showCancel: false,//关闭取消按钮
        })
      }
    },
    fail: function (res) {
      wx.hideLoading();
      wx.showModal({
        title: '温馨提示',
        content: res.data.error || '网络繁忙,请稍后重试!',
        showCancel: false,
      })
    },
    complete: function () {

    }
  })
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章