微信授權獲取使用者資訊
在我們開發小程式的時候,需要通過授權獲取使用者的資訊。
第一種使用wx.getUserInfo直接獲取微信頭像,暱稱
// 必須是在使用者已經授權的情況下呼叫 wx.getUserInfo({ success: function(res) { var userInfo = res.userInfo var nickName = userInfo.nickName var avatarUrl = userInfo.avatarUrl var gender = userInfo.gender //性別 0:未知、1:男、2:女 var province = userInfo.province var city = userInfo.city var country = userInfo.country } })
第二種方式使用wx.login()
這種方式即將被放棄,目前使用比較多的是的wx.login()。因為直接使用wx.getUserInfo是不能獲取更多的資訊的,如微信使用者的openid。 官方提示,需要傳送獲取到的code進行請求到微信的後端API。根據文件,只需要進行一個get請求到如下地址即可:
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_codeappid和secret在微信小程式後臺可以看到,
js_code為使用wx.login登入時獲取到的code引數資料,grant_type這個不用改動。
官方推薦
在login獲取到code,然後傳送到開發者後端,後端再通過介面去微信後端換取到openid和sessionKey之後,然後把session返回給前端,就已經完成登入行為。而login行為是靜默,不必授權的,不會對使用者造成騷擾。getUserInfo只是為了提供更優質的服務而存在,比如展示頭像暱稱,判斷性別,通過unionId和其他公眾號上已有的使用者畫像結合起來提供歷史資料。所以不必在剛剛進入小程式的時候就強制要求授權。相關程式碼如下所示。
JS程式碼 var userInfo= (wx.getStorageSync('userInfo')) if (userInfo) { wx.getUserInfo({ success: function (res) { that.setData({ nickName: res.userInfo.nickName, avatarUrl: res.userInfo.avatarUrl, }) }, fail: function () { console.log("獲取失敗!") }, complete: function () { console.log("獲取使用者資訊完成!") } }) } else { wx.login({ success: function (res) { console.log(res.code) if (res.code) { wx.getUserInfo({ withCredentials: true, success: function (res_user) { wx.request({ //後臺介面地址 url: 'https://xxxx.com/wx/login', data: { code: res.code }, method: 'GET', header: { 'content-type': 'application/json' }, success: function (res) { that.setData({ userInfo: res.errMsg.userInfo }) wx.setStorageSync('userInfo', res.data.userInfo); } }) }, fail: function () { wx.showModal({ title: '警告通知', content: '您點選了拒絕授權,將無法正常顯示個人資訊,點選確定重新獲取授權。', success: function (res) { if (res.confirm) { wx.openSetting({ success: (res) => { if (res.authSetting["scope.userInfo"]) {////如果使用者重新同意了授權登入 wx.login({ success: function (res_login) { if (res_login.code) { wx.getUserInfo({ withCredentials: true, success: function (res_user) { wx.request({ url: 'https://xxxx.com/wx/login', data: { code: res_login.code }, method: 'GET', header: { 'content-type': 'application/json' }, success: function (res) { that.setData({ userInfo: res.errMsg.userInfo }) wx.setStorageSync('userInfo', res.errMsg.userInfo); } }) } }) } } }); } }, fail: function (res) { } }) } } }) }, complete: function (res) { } }) } } }) } }, //globalData建議放在app.js,方便統一管理 globalData: { userInfo: null }
後端程式碼
由於我的後端是PHP寫的,用的是thinkphp5框架,框架地址:https://www.kancloud.cn/manual/thinkphp5/118003
/**
* 小程式登入
* @return array
*/
public function login() {
$code = input('post.code'); //這是從前端傳過來的code
$userInfo = input('post.userInfo');
$info = json_decode($userInfo, true);
$user = $info['userInfo'];
$memberModel = model('Member');
$appid = "小程式的appid"; //一定要是小程式的appid,不是微信公眾號的appid
$secret = "小程式的secret";
$url = "https://api.weixin.qq.com/sns/jscode2session?appid=". $appid."&secret=".$secret."&js_code=" . $code . "&grant_type=authorization_code";
//初始化curl
$ch = curl_init($url);
//3.設定引數
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//跳過證書驗證
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 從證書中檢查SSL加密演算法是否存在
$res = curl_exec($ch);
if(curl_errno($ch)){
var_dump(curl_error($ch));
}
$resArr = json_decode($res,1);
$data = array();
curl_close($ch);
$mapData = array();
//這裡我把使用者的資訊儲存起來,方便下次呼叫,資料庫結構我們在下面會介紹
if (!empty($resArr['openid'])) {
$res = $memberModel->checkMember($resArr['openid']);
Log::write('使用者資訊:' . $memberModel->getLastSql());
if ($res) {
$mapData['userInfo'] = $res;
$mapData['session_key'] = $resArr['session_key'];
return $this->resMap(200, $mapData, $mapData);
} else {
$data['nickName'] = $user['nickName'];
$data['avatarUrl'] = $user['avatarUrl'];
$data['m_province'] = $user['province'];
$data['m_city'] = $user['city'];
$data['m_gender'] = $user['gender'];
$data['m_language'] = $user['language'];
$data['signature'] = $info['signature'];
$data['iv'] = $info['iv'];
$data['m_uuid'] = showUuid();
$data['m_openid'] = $resArr['openid'];
$data['m_country'] = $resArr['country'];
$data['m_ip'] = GetIP();
$data['m_createtime'] = getDateTime(1);
$memberModel->addOne($data);
$mapData['userInfo'] = $data;
$mapData['session_key'] = $resArr['session_key'];
return $this->resMap(200, $mapData, $mapData);
}
} else {
return $this->resMap(4002, '登入失敗', '登入失敗');
}
}
/**
* 返回提示資訊
* @param $code string 錯誤碼 4001 空值 4002 格式不正確 4003 長度 4004 提示 200正確放回 ,0失敗
* @param $msg string 錯誤描述
* @param $data string 返回值
* @return array
*/
public function resMap($code, $msg, $data)
{
$map = array();
$map['errMsg'] = $msg;
$map['data'] = $data;
$map['errCode'] = $code;
return json($map);
}
以上就是核心程式碼,希望對大家有用。在上面,我們需要儲存使用者的資訊,因此我們需要資料庫表,下面就談到表的設計。
使用者表的設計
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `system_member`
-- ----------------------------
DROP TABLE IF EXISTS `system_member`;
CREATE TABLE `system_member` (
`m_id` INT(11) NOT NULL AUTO_INCREMENT,
`nickName` VARCHAR(50) DEFAULT NULL COMMENT '使用者暱稱',
`avatarUrl` VARCHAR(255) DEFAULT NULL COMMENT '頭像',
`m_province` VARCHAR(40) DEFAULT NULL COMMENT '省份',
`m_city` VARCHAR(50) DEFAULT NULL COMMENT '城市',
`m_name` VARCHAR(30) DEFAULT NULL COMMENT '真實姓名',
`m_gender` TINYINT(1) DEFAULT '3' COMMENT '使用者性別(1、男 2、女 3、未知)',
`m_createtime` DATETIME DEFAULT NULL COMMENT '建立時間',
`m_country` VARCHAR(100) DEFAULT NULL COMMENT '國家',
`m_language` VARCHAR(50) DEFAULT NULL COMMENT '語言',
`m_openid` VARCHAR(50) DEFAULT NULL COMMENT 'openID',
`m_ip` VARCHAR(15) DEFAULT NULL COMMENT 'IP',
`m_mobile` VARCHAR(20) DEFAULT NULL COMMENT '手機號碼',
`m_uuid` VARCHAR(50) DEFAULT NULL,
`m_username` VARCHAR(50) DEFAULT NULL COMMENT '使用者名稱',
`m_pwd` VARCHAR(50) DEFAULT NULL COMMENT '密碼',
`session_key` VARCHAR(255) DEFAULT NULL COMMENT '會話金鑰',
`unionid` VARCHAR(255) DEFAULT NULL COMMENT '使用者在開放平臺的唯一識別符號',
`signature` VARCHAR(255) DEFAULT NULL,
`iv` VARCHAR(255) DEFAULT NULL,
`k_id` VARCHAR(50) DEFAULT NULL,
`k_openid` VARCHAR(80) DEFAULT NULL,
PRIMARY KEY (`m_id`)
) ENGINE=INNODB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COMMENT='獲取使用者小程式資訊';
以上就是獲取使用者資訊的完整流程,下面我們附上一張使用者登入的流程圖。
如果大家有什麼不明白的地方,可以加入我們的微信交流群:731568857,裡面有很多技術資源。或者關注我們的微信公眾號。