1. 微信登錄思路:
1. 在main.js 中封裝公共函數,用于判斷用戶是否登錄
2. 在main.js 中分定義全局變量,用于存儲接口地址
3. 如果沒有登錄、則跳轉至登錄頁面
4. 進入登錄頁面
5. 通過 wx.login 獲取用戶的 code
6. 通過 code 獲取用戶的 SessionKey、OpenId 等信息【本應后臺接口、但是此處使用js發送請求】
7. 通過 openId 調用后臺 Api 獲取用戶的信息
8. 獲取成功,則說明已經授權過了,直接登錄成功
9. 獲取失敗,則說明沒有授權過,需要授權之后才能進行登錄
10. 用戶點擊頁面微信登錄按鈕【 】
11. 獲取用戶數據,然后調用后臺接口寫入數據庫
2. 在 applets/main.js 中添加如下
~~~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 中添加如下
~~~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 中添加如下:
~~~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
~~~php
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
~~~php
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. 完工!!!
- thinkphp6執行流程(一)
- php中use關鍵字用法詳解
- Thinkphp6使用騰訊云發送短信步驟
- 路由配置
- Thinkphp6,static靜態資源訪問路徑問題
- ThinkPHP6.0+ 使用Redis 原始用法
- smarty在thinkphp6.0中的最佳實踐
- Thinkphp6.0 搜索器使用方法
- 從已有安裝包(vendor)恢復 composer.json
- tp6with的用法,表間關聯查詢
- thinkphp6.x多對多如何添加中間表限制條件
- thinkphp6 安裝JWT
- 緩存類型
- 請求信息和HTTP頭信息
- 模型事件用法
- 助手函數匯總
- tp6集成Alipay 手機和電腦端支付的方法
- thinkphp6使用jwt
- 6.0session cookie cache
- tp6筆記
- TP6(thinkphp6)隊列與延時隊列
- thinkphp6 command(自定義指令)
- command(自定義指令)
- 本地文件上傳
- 緩存
- 響應
- 公共函數配置
- 七牛云+文件上傳
- thinkphp6:訪問多個redis數據源(thinkphp6.0.5 / php 7.4.9)
- 富文本編輯器wangEditor3
- IP黑名單
- 增刪改查 +文件上傳
- workerman 定時器操作控制器的方法
- 上傳文件到阿里云oss
- 短信或者郵箱驗證碼防刷代碼
- thinkphp6:訪問redis6(thinkphp 6.0.9/php 8.0.14)
- 實現關聯多個id以逗號分開查詢數據
- thinkphp6實現郵箱注冊功能的細節和代碼(點擊鏈接激活方式)
- 用mpdf生成pdf文件(php 8.1.1 / thinkphp v6.0.10LTS )
- 生成帶logo的二維碼(php 8.1.1 / thinkphp v6.0.10LTS )
- mysql數據庫使用事務(php 8.1.1 / thinkphp v6.0.10LTS)
- 一,創建過濾IP的中間件
- 源碼解析請求流程
- 驗證碼生成
- 權限管理
- 自定義異常類
- 事件監聽event-listene
- 安裝與使用think-addons
- 事件與多應用
- Workerman 基本使用
- 查詢用戶列表按拼音字母排序
- 擴展包合集
- 查詢用戶數據,但是可以通過輸入用戶昵稱來搜索用戶同時還要統計用戶的文章和粉絲數
- 根據圖片的minetype類型獲取文件真實拓展名思路
- 到處excel
- 用imagemagick庫生成縮略圖
- 生成zip壓縮包并下載
- API 多版本控制
- 用redis+lua做限流(php 8.1.1 / thinkphp v6.0.10LTS )
- 【thinkphp6源碼分析三】 APP類之父, 容器Container類
- thinkphp6表單重復提交解決辦法
- 小程序授權
- 最簡單的thinkphp6導出Excel
- 根據訪問設備不同訪問不同模塊
- 服務系統
- 前置/后置中間件
- 給接口api做簽名驗證(php 8.1.1 / thinkphp v6.0.10LTS )
- 6實現郵箱注冊功能的細節和代碼(點擊鏈接激活方式)
- 使用前后端分離的驗證碼(thinkphp 6.0.9/php 8.0.14/vue 3.2.26)
- 前后端分離:用jwt+middleware做用戶登錄驗證(php 8.1.1 / thinkphp v6.0.10LTS )
- vue前后端分離多圖上傳
- thinkphp 分組、頁面跳轉與ajax
- thinkphp6 常用方法文檔
- 手冊里沒有的一些用法
- Swagger 3 API 注釋
- PHP 秒級定時任務
- thinkphp6集成gatewayWorker(workerman)實現實時監聽
- thinkphp6按月新增數據表
- 使用redis 實現消息隊列
- api接口 統一結果返回處理類
- 使用swoole+thinkphp6.0+redis 結合開發的登錄模塊
- 給接口api做簽名驗證
- ThinkPHP6.0 + UniApp 實現小程序的 微信登錄
- ThinkPHP6.0 + Vue + ElementUI + axios 的環境安裝到實現 CURD 操作!
- 異常$e
- 參數請求驗證自定義和異常錯誤自定義