微信小程序授权登录+Tp5后端

在网上查了好多资料,也参考了一些博主的方法,然后融合自己的方法写了个授权登录,废话不多说,直接上代码,伸手党可以好好看看了

先上效果截图:

授权界面
授权界面
点击授权界面

哎,不会用csdn的编辑器,本来想把两张图片并排的,谁知道弄不来,算了将就看吧,

index.wxml代码:

<view wx:if="{{canIUse}}">
    <view class='header'>
        <image src='/images/wx_login.png'></image>
    </view>
 
    <view class='content'>
        <view>申请获取以下权限</view>
        <text>获得你的公开信息(昵称,头像等)</text>
    </view>
 
    <button class='bottom' type='primary' open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="bindGetUserInfo">
        授权登录
    </button>
</view>
 
<view wx:else>请升级微信版本</view>

index.wxss样式代码:

.header {
    margin: 90rpx 0 90rpx 50rpx;
    border-bottom: 1px solid #ccc;
    text-align: center;
    width: 650rpx;
    height: 300rpx;
    line-height: 450rpx;
}
 
.header image {
    width: 200rpx;
    height: 200rpx;
}
 
.content {
    margin-left: 50rpx;
    margin-bottom: 90rpx;
}
 
.content text {
    display: block;
    color: #9d9d9d;
    margin-top: 40rpx;
}
 
.bottom {
    border-radius: 80rpx;
    margin: 70rpx 50rpx;
    font-size: 35rpx;
}

index.js代码

var app = getApp();
var url = app.d.ceshiUrl + 'login';
var login = function(code, encrypteData, iv) {
  var that = this
  //创建一个dialog提示
  wx.showToast({
    title: '正在登录...',
    icon: 'loading',
    duration: 5000
  });
  wx.request({
    url: url,
    method: 'get',
    data: {
      code: code,
      encrypteData: encrypteData,
      iv: iv
    },
    header: {
      'Content-Type': 'application/json'
    },
    success: function(res) {
      wx.hideToast()
      //console.log('服务器返回' + res.data)
      app.globalData.userInfo = res.data
    },
    fail: function() {
      wx.showToast({
        title: '网络错误!',
        duration: 2000
      })
    },
    complete: function() {

    }
  })
}
Page({
  data: {
    //判断小程序的API,回调,参数,组件等是否在当前版本可用。
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  onLoad: function() {
    var that = this
    wx.login({
      success: function(res) { //登录成功
        //console.log(res)
        if (res.code) {
          var code = res.code
          wx.getUserInfo({ //getUserInfo流程
            success: function(data) { //getUserInfo获取用户信息成功
              //console.log(data)
              //encrypteData加密密文,iv偏移向量,encodeURIComponent把加密字符串解密成URI字符串
              var encryptedData = encodeURIComponent(data.encryptedData);
              var iv = data.iv;
              //请求自己的服务器
              login(code, encryptedData, iv);
              //已经授权的用户
              wx.switchTab({
                url: '../rec/rec',
              })
            }
          })
        } else {
          console.log('用户没有进行授权!' + res.errMsg)
        }
      }
    });
  },
  bindGetUserInfo: function(e) {
    //console.log(e)
    if (e.detail.userInfo) {
      //用户按了允许授权的按钮
      var that = this
      wx.login({
        success: function(res) {
          if (res.code) {
            var code = res.code
            wx.getUserInfo({
              success: function(data) {
                var encryptedData = encodeURIComponent(data.encryptedData);
                var iv = data.iv;
                //请求自己的服务器
                login(code, encryptedData, iv);
              }
            })
          }
        }
      })
      //授权成功后,跳转进入小程序首页
      wx.switchTab({
        url: '../rec/rec'
      })
    } else {
      //用户按了拒绝按钮
      wx.showModal({
        title: '警告',
        content: '您点击了拒绝授权,将无法进入小程序,请授权之后再进入!!!',
        showCancel: false,
        confirmText: '返回授权',
        success: function(res) {
          if (res.confirm) {
            console.log('用户点击了“返回授权”')
          }
        }
      })
    }
  },
})

后端TP5代码比较多,请耐心看完,不然剩下的你可以自行脑补,我也省事了。

/**
 * 发送HTTP请求方法
 * @param  string $url    请求URL
 * @param  array  $params 请求参数
 * @param  string $method 请求方法GET/POST
 * @return array  $data   响应数据
 */
function httpCurl($url, $params, $method = 'POST', $header = array(), $multi = false){
    date_default_timezone_set('PRC');
    $opts = array(
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_HTTPHEADER     => $header,
        CURLOPT_COOKIESESSION  => true,
        CURLOPT_FOLLOWLOCATION => 1,
        CURLOPT_COOKIE         =>session_name().'='.session_id(),
    );
    /* 根据请求类型设置特定参数 */
    switch(strtoupper($method)){
        case 'GET':
            // $opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
            // 链接后拼接参数  &  非?
            $opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
            break;
        case 'POST':
            //判断是否传输文件
            $params = $multi ? $params : http_build_query($params);
            $opts[CURLOPT_URL] = $url;
            $opts[CURLOPT_POST] = 1;
            $opts[CURLOPT_POSTFIELDS] = $params;
            break;
        default:
            throw new Exception('不支持的请求方式!');
    }
    /* 初始化并执行curl请求 */
    $ch = curl_init();
    curl_setopt_array($ch, $opts);
    $data  = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);
    if($error) throw new Exception('请求发生错误:' . $error);
    return  $data;
}
/**
 * 微信信息解密
 * @param  string  $appid  小程序id
 * @param  string  $sessionKey 小程序密钥
 * @param  string  $encryptedData 在小程序中获取的encryptedData
 * @param  string  $iv 在小程序中获取的iv
 * @return array 解密后的数组
 */
function decryptData( $appid , $sessionKey, $encryptedData, $iv ){
    $OK = 0;
    $IllegalAesKey = -41001;
    $IllegalIv = -41002;
    $IllegalBuffer = -41003;
    $DecodeBase64Error = -41004;
 
    if (strlen($sessionKey) != 24) {
        return $IllegalAesKey;
    }
    $aesKey=base64_decode($sessionKey);
 
    if (strlen($iv) != 24) {
        return $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 $IllegalBuffer;
    }
    if( $dataObj->watermark->appid != $appid )
    {
        return $DecodeBase64Error;
    }
    $data = json_decode($result,true);
 
    return $data;
}

/**
 * 请求过程中因为编码原因+号变成了空格
 * 需要用下面的方法转换回来
 */
function define_str_replace($data)
{
    return str_replace(' ','+',$data);
}

微信获取appid代码,这里面我把获取到的appid写入数据库

//微信登录
 	public function wxlogin(){
 		$get = input('get.');
 		$param['appid'] = '';    //小程序id
 		$param['secret'] = '';    //小程序密钥
 		$param['js_code'] = define_str_replace($get['code']);
 		$param['grant_type'] = 'authorization_code';
 		$http_key = httpCurl('https://api.weixin.qq.com/sns/jscode2session', $param, 'GET');
    $session_key = json_decode($http_key,true);
    //print_r(http_build_query($param));
    if (!empty($session_key['session_key'])) {
    	$appid = $param['appid'];
    	$encrypteData = urldecode($get['encrypteData']);
    	$iv = define_str_replace($get['iv']);
    	$errCode = decryptData($appid, $session_key['session_key'], $encrypteData, $iv);
    	//把appid写入到数据库中
    	$data['appid'] = $errCode['openId'];
    	$data['nicheng'] = $errCode['nickName'];
    	$data['publishtime'] = time();
    	$data['sex'] = $errCode['gender'];
    	if (false == $this->user->where(['appid' => $data['appid']])->find()) {
    		$this->user->insert($data);
    	}else{
    		$value = $this->user->where(['appid' => $data['appid']])->field('name,tel,birthday,industry,address')->select();
    	}
    	$array = array_merge_recursive($errCode, $value);
    	return json($array);
    }else{
    	echo '获取session_key失败!';
    }
 	}

到这里整个代码就完了,转载请注明出处

  • 13
    点赞
  • 34
    收藏
  • 打赏
    打赏
  • 13
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 13

打赏作者

it0_soft

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值