本文详细讲解如何使用微信小程序登录,安全的获取信息,并安全的获取完整的用户信息。
开发工具调试基础库:2.23.0
小程序用的是编辑器自带的默认demo
wxml
<!--index.wxml--> <view class="container"> <view class="userinfo"> <block wx:if="{{canIUseOpenData}}"> <view class="userinfo-avatar" bindtap="bindViewTap"> <open-data type="userAvatarUrl"></open-data> </view> <open-data type="userNickName"></open-data> </block> <block wx:elif="{{!hasUserInfo}}"> <button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button> <button wx:elif="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button> <view wx:else> 请使用1.4.4及以上版本基础库 </view> </block> <block wx:else> <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image> <text class="userinfo-nickname">{{userInfo.nickName}}</text> </block> </view> <view> <button bindtap="getUserProfile">获取用户信息</button> </view> <view class="usermotto"> <text class="user-motto">{{motto}}</text> </view> </view>
js
// index.js // 获取应用实例 const app = getApp() Page({ data: { motto: 'Hello World', userInfo: {}, hasUserInfo: false, canIUse: wx.canIUse('button.open-type.getUserInfo'), canIUseGetUserProfile: false, canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需尝试获取用户信息可改为false }, // 事件处理函数 bindViewTap() { wx.navigateTo({ url: '../logs/logs' }) }, onLoad() { if (wx.getUserProfile) { this.setData({ canIUseGetUserProfile: true }) } }, getUserProfile(e) { // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗 wx.getUserProfile({ desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写 success: (res) => { console.log(res) this.setData({ userInfo: res.userInfo, hasUserInfo: true }) var postdata = res; wx.login({ success (res) { if (res.code) { postdata.code = res.code; //发起网络请求 wx.request({ url: 'http://您的域名/wxapp/login', //仅为示例,并非真实的接口地址 data: postdata, method:'POST', header: { // 'content-type': 'application/x-www-form-urlencoded' }, success (res) { //调用时 console.log(res) } }) } else { console.log('登录失败!' + res.errMsg) } } }) }, fail:(error)=>{ console.log(error) } }) }, getUserInfo(e) { // 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息 console.log(e) this.setData({ userInfo: e.detail.userInfo, hasUserInfo: true }) } })
PHP
<?php namespace app\home\plugins; use app\home\c\CommonController; use frphp\lib\Controller; use frphp\extend\Page; class WxappController extends CommonController { function _init(){ header('Access-Control-Allow-Origin:*'); parent::_init(); } function login(){ $postStr = file_get_contents('php://input'); $params = json_decode($postStr,1); //var_dump($params); //signature rawData code //signature = sha1( rawData + session_key ) $signature = sha1($params['rawData'].$params['code']); if($signature!=$params['signature']){ echo '信息验证成功!'; //获取session_key $wxappid = 'wxb881c912hdsasads'; $wxscret = 'ef34897e9eb35026cf887c92a45909e6'; $url = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$wxappid.'&secret='.$wxscret.'&js_code='.$params['code'].'&grant_type=authorization_code'; //解密敏感数据 $json = curl_http($url); $res = json_decode($json,1); //一般都是appid和密钥错误,或者IP不在白名单 if(isset($res['errcode'])){ echo $res['errmsg']; exit; } $sessionKey = $res['session_key']; $openid = $res['openid'];//解析到openid $data = $this->decryptData($wxappid, $sessionKey, $params['encryptedData'], $params['iv']); if ($data['code'] == 0) { var_dump($data);//这里就是从加密字符串里面解析出来的用户数据 } else { print($data['msg'] . "\n");//错误信息 } }else{ echo '信息验证失败!'; } } public function decryptData( $appid, $sessionKey, $encryptedData, $iv) { if (strlen($sessionKey) != 24) { return ['code'=>1,'msg'=>-41001]; } $aesKey=base64_decode($sessionKey); if (strlen($iv) != 24) { return ['code'=>1,'msg'=>-41002]; } $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 ['code'=>1,'msg'=>-41003]; } if( $dataObj->watermark->appid != $appid ) { return ['code'=>1,'msg'=>-41003]; } return ['code'=>0,'data'=>$result]; } } ?>
解密出来的信息如下:
array(2) { ["code"]=> int(0) ["data"]=> string(311) "{"nickName":"如沐春²⁰²²","gender":0,"language":"zh_CN","city":"","province":"","country":"","avatarUrl":"https://thirdwx.qlogo.cn/mmopen/vi_32/EEyLjUID6AbabicsF5Dtxbmic3QPAk1AmNM3Q1kxMzcPZ7c1erBvNbd8NveCFXfKPGSrxKg2K47R48Q5wAaxb3cA/132","watermark":{"timestamp":1647566626,"appid":"wxb881c912hdsasads"}}" }