小程序基礎開發(三):授權,獲取用戶信息,註冊,登錄,簡單封裝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 () {

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