微信授权登录,并验证微信用户手机号

1.前端发起请求

//验证微信用户绑定的手机号
checkWXPhoneNumber(){
	uni.request({
		url: this.$C.company.apiHttps + 'api/v1/user/check_phone',
		method: 'POST',
		data:{
			yhid:this.$C.user.yhid,
			wxPhoneNumber:this.wxUserInfo.phoneNumber
			},
			success: res => {
				(res.data.errorCode!=0){
				uni.redirectTo({
				  url:'/pages/notfound/notfound?errMsg='+ res.data.msg
				})
			}
		}
	});
}

2.php服务端手机号码验证代码

 //验证微信绑定的手机号
    public static function checkPhoneNum()
    {
        $params = input('post.');
        $yhid = $params['yhid'];
        $wxPhoneNumber = $params['wxPhoneNumber'];
        $user = SyhqxModel::where([
            'YHID' => $yhid,
        ])->find();

        if(!$user){
            return json(new UserException(['msg'=> '没有找到【'.$yhid.'】用户' ]), 2000);
        }
        return self::comparePhoneNumber($wxPhoneNumber,$user->Remark1);
    }
    //保存微信绑定的手机号到用户表
    public static function savePhoneNum(){
        $params = input('post.');
        $yhid = $params['yhid'];
        $wxPhoneNumber = $params['wxPhoneNumber'];
        $user = SyhqxModel::where([
            'YHID' => $yhid,
        ])->find();

        if(!$user){
            return json(new UserException(['msg'=> '没有找到【'.$yhid.'】用户' ]), 2000);
        }

        if($user->Remark1){
            return self::comparePhoneNumber($wxPhoneNumber,$user->Remark1);
        }
        else
        {
            $user->save([
                'TrigTag' => !$user['TrigTag'],
                'Remark1' => $wxPhoneNumber
            ]);
            return json(new SuccessMessage(['msg'=>'保存成功!']), 201);

        }
    }



    //对比电话号码
    private static function  comparePhoneNumber($wxPhoneNumber,$userPhoneNumber)
    {
        if($wxPhoneNumber==$userPhoneNumber)
        {
            return json(new SuccessMessage(['msg'=>'匹配成功!']), 201);
        }
        else
        {
            return json(new UserException(['msg'=>'微信用户绑定的号码不匹配']), 2002);
        }
    }

3.微信授权页面代码

<template>
	<view class="bg-white flex flex-column justify-center align-center">
		<view style="width: 80%;">
			<view class="py-5 text-center">
				<image src="../../static/icos/weixin.png" style="width: 150rpx;height: 150rpx;" />

			</view>
			<view class="line"></view>
			<view class="py-5">
				<view class="font-md text-dark font-weight-bolder text-left">申请获取你的以下信息</view>
				<view class="font-md text-light-muted">获得你的公开信息(呢称、头像等)</view>
			</view>
			<view v-if="wxUser == '' || wxUser == undefined" class="pt-3">
				<button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber"
					style="height: 80rpx; border-radius: 60rpx;background-color: #00C800;" class="text-white font-md"
					withCredentials="true">
					授权登录
				</button>
			</view>
		</view>
	</view>
</template>

<script>
	import WXBizDataCrypt from '../../common/WXBizDataCrypt.js'
	export default {
		data() {
			return {
				sessionKey: "",
				openId: "",
				wxUserinfo: "",
				wxPhoneNumber: '',
			}
		},
		onShow() {
			this.wxLogin();
		},
		methods: {
			//保存电话号码到用户表
			savePoneNumber() {
				uni.request({
					url: this.$C.company.apiHttps + 'api/v1/user/save_phone',
					method: 'POST',
					data: {
						yhid: this.$C.user.yhid,
						wxPhoneNumber: this.wxPhoneNumber
					},
					success: res => {
						if (res.data.code == 201) {
							console.log(res);
							uni.showToast({
								icon: 'success',
								title: '授权成功!',
								duration: 500,
								success: () => {
									this.appLoginWx(this.wxPhoneNumber)
								}
							})
						} else {
							uni.showToast({
								icon: 'error',
								title: '授权失败!',
								duration: 500,
								success: () => {
									uni.redirectTo({
										url: '/pages/notfound/notfound'
									})
								}
							})
						}

					}
				});
			},

			//微信登录
			wxLogin() {
				uni.login({
					provider: 'weixin',
					success: res => {
						let code = res.code;
						uni.request({
							url: this.$C.company.apiHttps + 'api/v1/wx/openid',
							method: 'POST',
							data: {
								code: code
							},
							success: res => {
								this.sessionKey = res.data.session_key;
								this.openId = res.data.openid;
							}
						});
					}
				})
			},
			//读取手机号码 
			getPhoneNumber(e) {
				if (this.sessionKey == "") {
					uni.showModal({
						title: "获取登录信息失败!"
					})
					return
				}
				if (e.detail.errMsg == "getPhoneNumber:ok") {
					var appId = this.$C.appId;
					var sessionKey = this.sessionKey
					var encryptedData = e.detail.encryptedData
					var iv = e.detail.iv
					var pc = new WXBizDataCrypt(appId, sessionKey)
					var data = pc.decryptData(encryptedData, iv)
					console.log('解密后 data: ', data)
					this.wxPhoneNumber = data.phoneNumber;

					this.savePoneNumber();
				}
			},

			appLoginWx(phoneNumber) {
				// #ifdef MP-WEIXIN
				uni.getProvider({
					service: 'oauth',
					success: function(res) {
						if (~res.provider.indexOf('weixin')) {
							uni.login({
								provider: 'weixin',
								success: (res2) => {
									uni.getUserInfo({
										provider: 'weixin',
										success: (info) => { //这里请求接口
											info.userInfo.phoneNumber = phoneNumber
											uni.setStorageSync('wxUser', info.userInfo)
											uni.switchTab({
												url: '/pages/index/index'
											});
										},
										fail: () => {
											uni.showToast({
												title: "微信登录授权失败",
												icon: "none"
											});
										}
									})

								},
								fail: () => {
									uni.showToast({
										title: "微信登录授权失败",
										icon: "none"
									});
								}
							})

						} else {
							uni.showToast({
								title: '请先安装微信或升级版本',
								icon: "none"
							});
						}
					}
				});
				//#endif
			}
		}
	}
</script>


4.php服务端微信验证代码

class UserToken extends Token
{
    protected $code;
    protected $wxAppID;
    protected $wxAppSecret;
    protected $wxLoginUrl;
    private $wxResult;
    private $yhid;

    function __construct($code)
    {
        $this->code = $code;
        $this->wxAppID = config('wx.app_id');
        $this->wxAppSecret = config('wx.app_secret');
        $this->wxLoginUrl = sprintf(config('wx.login_url'),
            $this->wxAppID, $this->wxAppSecret, $this->code);
    }

    public function getOpenId()
    {
        $result = curl_get($this->wxLoginUrl);
        $this->wxResult = json_decode($result, true);
        return $this->wxResult;
    }

    public function get($yhid){

        $this->getOpenId();
        $this->yhid = $yhid;
        if(empty($this->wxResult)){

            throw  new Exception('获取session_key与openID时异常,微信内部错误');

        }else{
            $loginFail = array_key_exists('errcode', $this->wxResult);
            if($loginFail){
                $this->processLoginError($this->wxResult);
            }else{
                return $this->grantToken($this->wxResult,$this->yhid);
            }
        }
    }

    private function grantToken(){
        //拿到openid
        //数据库里看一下,这个openid是不是已经存在
        //如果存在 则不处理, 如果不存再根据yhid查询用户,并把openid保存到对应用户
        //生成令牌,准备缓存数据, 定入缓存
        //把令牌返回到客户端去
        //key:令牌
        //value:wxResult,yhid,scope
        $openid = $this->wxResult['openid'];
        $user = SyhqxModel::getuserByOpenid($openid);
        if($user){
            $uid = $user->YHID;
        }else{
            $user = Syhqx::getUserByYhid($this->yhid);
            if($user){
                $uid =  $this->saveUser($user, $openid);
            }else{
                throw new UserException();
            }
        }
        $cashedValue = $this->prepareCashedValue($uid);
        $token = $this->saveToCach($cashedValue);
        return $token;
    }

    //写入缓存,返回令牌
    private function saveToCach($cashedValue){
        $key = self::generateToken();
        $value = json_encode($cashedValue);
        $expire_in = config('setting.token_expire_in');

        $request = cache($key, $value, $expire_in);
        if(!$request){
            throw new TokenException([
                'msg' => '服务器异常',
                'errorCode' => 10005
            ]);
        }

        return $key;
    }

    //准备缓存数据
    private function prepareCashedValue ($uid){
        $cashedValue = $this->wxResult;
        $cashedValue['uid'] = $uid;
        $cashedValue['scope'] = 16;
        return $cashedValue;
    }

    //保存openid到用户表
    private function saveUser($user,$openid){
        $user['Remark1'] = $openid;
        $user->save();
        return $user->YHID;
    }

    //处理微信登录异常
    private  function processLoginError(){
        throw new WeChatException([
            'msg' => $this->wxResult['errmsg'],
            'errorCode' => $this->wxResult['errcode']
        ]);
    }
}
posted @ 2022-08-27 16:23  panbin_2006  阅读(656)  评论(0编辑  收藏  举报