ThinkPHP6.0 + UniApp 實現小程序的 微信登錄


  1. 微信登錄思路:

    1. 在main.js 中封裝公共函數,用於判斷用戶是否登錄
    2. 在main.js 中分定義全局變量,用於存儲接口地址
    3. 如果沒有登錄、則跳轉至登錄頁面
    4. 進入登錄頁面
    5. 通過 wx.login 獲取用戶的 code
    6. 通過 code 獲取用戶的 SessionKey、OpenId 等信息【本應后台接口、但是此處使用js發送請求】
    7. 通過 openId 調用后台 Api 獲取用戶的信息
    8. 獲取成功,則說明已經授權過了,直接登錄成功
    9. 獲取失敗,則說明沒有授權過,需要授權之后才能進行登錄
    10. 用戶點擊頁面微信登錄按鈕【 <button open-type="getUserInfo"></button>】
    11. 獲取用戶數據,然后調用后台接口寫入數據庫
  2. 在 applets/main.js 中添加如下

    // 封裝全局登錄函數
    // backpage, backtype 2個參數分別代表:
    // backpage : 登錄后返回的頁面
    // backtype : 打開頁面的類型[1 : redirectTo 2 : switchTab]
    Vue.prototype.checkLogin = function( backpage, backtype ){
    	// 同步獲取本地數據(uid、隨機碼、用戶名、頭像)
    	var user_id = uni.getStorageSync('user_id');
    	var user_nu = uni.getStorageSync('user_nu');
    	var user_nm = uni.getStorageSync('user_nm');
    	var user_fa = uni.getStorageSync('user_fa');
    	if( user_id == '' || user_nu == '' || user_fa == ''){
    		// 使用重定向的方式跳轉至登錄頁面
    		uni.redirectTo({url:'../login/login?backpage='+backpage+'&backtype='+backtype});
    		return false;
    	}
    	// 登錄成功、已經登錄返回數組 [用戶 id, 用戶隨機碼, 用戶昵稱, 用戶表情]
    	return [user_id, user_nu, user_nm, user_fa];
    }
    // 定義一個全局的請求地址
    Vue.prototype.apiServer = 'http://0608.cc/'
    
  3. 在 pages/login/login.vue 中添加如下

    <template>
    	<view>
    		<!-- login view html start -->
    		<view>
    			<view>
    				<view class="header"><image src="/static/img/public/login-wx.png"></image></view>
    				<view class="content">
    					<view>申請獲取以下權限</view>
    					<text>獲得你的公開信息(昵稱,頭像、地區等)</text>
    				</view>
    				<button class="bottom" type="primary" open-type="getUserInfo" withCredentials="true" lang="zh_CN" @getuserinfo="wxGetUserInfo">授權登錄</button>
    			</view>
    		</view>
    		<!-- login view html end -->
    	</view>
    </template>
    
    <script>
    export default {
    	data() {
    		return {
    			appid: '*************',
    			secret: '*************************',
    			code: '',
    			sessionKey: '',
    			openId: '',
    			userInfo: {
    				avatarUrl: '',
    				city: '',
    				country: '',
    				gender: 1,
    				language: '',
    				nickName: ''
    			},
    			pageOption: {}
    		};
    	},
    	methods: {
    		// 第一授權獲取用戶信息 ===》按鈕觸發
    		wxGetUserInfo() {
    			let _self = this;
    			// 1.獲取用戶的信息
    			uni.getUserInfo({
    				provider: 'weixin',
    				success: ( infoRes ) => {
    					console.log( infoRes )
    					_self.userInfo = infoRes.userInfo
    					// 2.提交數據到后台、寫入數據庫
    					uni.request({
    						url: _self.apiServer + 'appletsUserInfo',
    						data: {
    							openid: _self.openId,
    							avatarUrl: _self.userInfo.avatarUrl,
    							city: _self.userInfo.city,
    							country: _self.userInfo.country,
    							gender: _self.userInfo.gender,
    							language: _self.userInfo.language,
    							nickName: _self.userInfo.nickName
    						},
    						method: 'POST',
    						success: res => {
    							if( res.data.code != 0 )
    							{
    								uni.showToast({ title: res.data.msg, icon: 'none' });
    								return false;
    							}
    							// 用戶信息寫入緩存
    							uni.showToast({title: '登錄成功'})
    							uni.setStorageSync( 'user_id', res.data.res.u_id );
    							uni.setStorageSync( 'user_nm', res.data.res.u_nickName );
    							uni.setStorageSync( 'user_fa', res.data.res.u_avatarUrl );
    							uni.setStorageSync( 'user_nu', res.data.res.u_regtime );
    							// 然后跳回原頁面
    							if( _self.pageOption.backtype == 1 )
    							{
    								uni.redirectTo({ url: _self.pageOption.backpage })
    							}else{
    								uni.switchTab({ url: _self.pageOption.backpage })
    							}
    						},
    						fail: () => {
    							uni.showToast({ title: '用戶信息操作失敗', icon: 'none' });
    						}
    					});
    				},
    				fail: () => {
    					uni.showToast({ title: '獲取用戶信息失敗', icon: 'none' });
    				}
    			});
    			return false
    		},
    		// 登錄
    		login() {
    			let _self = this;
    
    			// 0. 顯示加載的效果
    			uni.showLoading({
    				title: '登錄中...'
    			});
    
    			// 1. wx 獲取登錄用戶 code
    			uni.login({
    				provider: 'weixin',
    				success: loginRes => {
    					console.log(loginRes);
    					_self.code = loginRes.code;
    					// 2. 將用戶登錄code傳遞到后台置換用戶SessionKey、OpenId等信息
    					uni.request({
    						url:
    							'https://api.weixin.qq.com/sns/jscode2session?appid=' +
    							_self.appid +
    							'&secret=' +
    							_self.secret +
    							'&js_code=' +
    							_self.code +
    							'&grant_type=authorization_code',
    						success: codeRes => {
    							console.log(codeRes);
    							_self.openId = codeRes.data.openid;
    							_self.sessionKey = codeRes.data.session_key;
    							// 3.通過 openId 判斷用戶是否授權
    							uni.request({
    								url: _self.apiServer + 'loginApplets',
    								data: {
    									openid: _self.openId
    								},
    								method: 'POST',
    								success: openIdRes => {
    									console.log(openIdRes);
    									// 隱藏loading
    									uni.hideLoading();
    									// 還沒授權登錄、請先授權然后登錄
    									if (openIdRes.data.code == 1) {
    										// 提示消息、讓用戶授權
    										uni.showToast({ title: openIdRes.data.msg, icon: 'none' });
    									}
    									// 已經授權了、查詢到用戶的數據了
    									if (openIdRes.data.code == 0) {
    										// 用戶信息寫入緩存
    										uni.showToast({title: '登錄成功'})
    										uni.setStorageSync( 'user_id', openIdRes.data.res.u_id );
    										uni.setStorageSync( 'user_nm', openIdRes.data.res.u_nickName );
    										uni.setStorageSync( 'user_fa', openIdRes.data.res.u_avatarUrl );
    										uni.setStorageSync( 'user_nu', openIdRes.data.res.u_regtime );
    										// 然后跳回原頁面
    										if( _self.pageOption.backtype == 1 )
    										{
    											uni.redirectTo({ url: _self.pageOption.backpage })
    										}else{
    											uni.switchTab({ url: _self.pageOption.backpage })
    										}
    									}
    								},
    								fail: () => {
    									uni.showToast({ title: '獲取授權信息失敗', icon: 'none' });
    									return false;
    								}
    							});
    						},
    						fail: () => {
    							uni.showToast({ title: '獲取 SesssionKey OpenId 失敗', icon: 'none' });
    							return false;
    						}
    					});
    				},
    				fail: () => {
    					uni.showToast({ title: '獲取 code 失敗', icon: 'none' });
    					return false;
    				}
    			});
    			return false;
    		}
    	},
    	onLoad( options ) {
    		// 接收跳轉的參數
    		this.pageOption = options
    		//默認加載
    		this.login();
    	}
    };
    </script>
    
    <style>
    .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;
    }
    </style>
    
  4. 在 pages/my/my.vue 中添加如下:

    <template>
    	<view>我的頁面</view>
    </template>
    
    <script>
    var loginRes;
    export default {
    	data() {
    		return {};
    	},
    	onLoad() {
    		// 加載定義好的方法
    		loginRes = this.checkLogin('../my/my', 2);
    		// 沒有登錄成功,返回空
    		if (!loginRes) {
    			return;
    		}
    	},
    	methods: {}
    };
    </script>
    
    <style></style>
    
  5. PHP 接口 loginApplets

    public function loginApplets(Request $request, UserInfo $userInfo)
    {
        // 獲取數據
        $data['u_openid'] = $request->param('openid', '');
        // 驗證數據
        $rule = [
            'u_openid' => 'require|max:200|min:10'
        ];
        $message = [
            'u_openid.require' => 'openid 不能為空',
            'u_openid.max'     => 'openid 格式錯誤',
            'u_openid.min'     => 'openid 格式錯誤'
        ];
        $validate = Validate::rule($rule)->message($message);
        if (!$validate->check($data)) {
            return json(['code' => 1, 'msg' => $validate->getError(), 'res' => null]);
        }
        // 根據 openid 判斷是否存在
        $where['u_openid'] = $data['u_openid'];
        $user = $userInfo->selOne($where);
        if (!$user) {
            return json(['code' => 1, 'msg' => '還沒授權登錄、請先授權然后登錄', 'res' => $user]);
        }
        return json(['code' => 0, 'msg' => '已授權獲取到用戶的數據', 'res' => $user]);
    }
    
  6. PHP 接口 appletsUserInfo

    public function appletsUserInfo(Request $request, UserInfo $userInfo)
    {
        // 獲取數據
        $data['u_openid'] = $request->param('openid', '');
        $data['u_avatarUrl'] = $request->param('avatarUrl', '');
        $data['u_city'] = $request->param('city', '');
        $data['u_country'] = $request->param('country', '');
        $data['u_gender'] = $request->param('gender', '');
        $data['u_language'] = $request->param('language', '');
        $data['u_nickName'] = $request->param('nickName', '');
        // 驗證數據
        $rule = [
            'u_openid' => 'require|max:200|min:10',
            'u_avatarUrl' => 'require',
            'u_nickName' => 'require'
        ];
        $message = [
            'u_openid.require'      => 'openid 不能為空',
            'u_openid.max'          => 'openid 格式錯誤',
            'u_openid.min'          => 'openid 格式錯誤',
            'u_avatarUrl.require'   => '用戶頭像 不能為空',
            'u_nickName.max'        => '用戶名 格式錯誤',
        ];
        $validate = Validate::rule($rule)->message($message);
        if (!$validate->check($data)) {
            return json(['code' => 1, 'msg' => $validate->getError(), 'res' => null]);
        }
    
        // 根據 openid 判斷是否存在
        $where['u_openid'] = $data['u_openid'];
        $user = $userInfo->selOne($where);
    
        // 存在、執行修改
        if ($user) {
            $user_res = $userInfo->updOne($where, $data);
            $res = [];
            $res['u_id'] = $user['u_id'];
            $res['u_regtime'] = $user['u_regtime'];
        }
    
        // 不存在、執行添加
        if (empty($user)) {
            $res = [];
            $res = $data;
            $res['u_regtime'] = time();
            $res['u_id'] = $userInfo->addOne($res);
        }
    
        // 判斷是否添加成功
        if (empty($res['u_id'])) {
            return json(['code' => 1, 'msg' => '注冊失敗,返回重試', 'res' => null]);
        }
        return json(['code' => 0, 'msg' => 'ok', 'res' => $res]);
    }
    
  7. 完工!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM