小言_互联网的博客

微信小程序 - 实现手机号登录--授权并获取手机号保存至本地

1007人阅读  评论(0)

详细代码请见文档最下方,仅供参考,更多需要请查看官方文档

一、

微信官方文档 | 获取手机号

这是服务端的

 这是我们前端获取手机号需要给接口传递的两个参数

 

 注意:

参数一:获取access_token需要用到小程序密钥,这个需要从服务端获取,也就是需要请求后端接口获取access_token,千万不要将小程序密钥写在前端代码中,必须要从服务端获取。

参数二:code的获取我们可以点击后面的 "手机号获取凭证" 查看用法,很简单。下面 二、 就是手机号获取凭证地址。

二、

 微信官方文档 | 手机号获取凭证

注意:这里有基础库版本限制,所以我们最好做一下低版本兼容处理;

 

个人使用时碰到的坑:

微信开放社区 | 使用getPhoneNumber获取手机号code,微信PC拿不到code,手机端可以获取到? 

详细实现代码:


  
  1. <template>
  2. <view class="flex">
  3. <view class="title">
  4. <view class="logo">
  5. <image src="/static/image/logo.png" mode="widthFix" />
  6. </view>
  7. </view>
  8. <!-- 手机号登录 --授权并获取手机号保存至本地 -->
  9. <button
  10. type= "default"
  11. class= "loginButton"
  12. open-type= "getPhoneNumber"
  13. @ getphonenumber= "getPhoneNumber"
  14. >
  15. <view class="row">
  16. <view class="icon">
  17. <u-icon name="weixin-fill" size="28"> </u-icon>
  18. </view>
  19. <view style="font-size: 30rpx">微信登录 </view>
  20. </view>
  21. </button>
  22. <!-- 协议选择 -->
  23. <view class="serve-rule">
  24. <u-checkbox-group size="24" @click="changeCheckStatus">
  25. <u-checkbox
  26. class= "checkbox"
  27. v-model= "checkStatus"
  28. activeColor= "#ff414e"
  29. > </u-checkbox>
  30. </u-checkbox-group>
  31. <view class="protocol-prompt">
  32. <text @click="changeCheckStatus">本人理解并同意 </text>
  33. <text class="serve-label" @click.stop="onServiceAgreement"
  34. >《隐私政策》</text
  35. >
  36. <text class="serve-label" @click.stop="onUserAgreement"
  37. >《用户协议》</text
  38. >
  39. </view>
  40. </view>
  41. <u-toast ref="uToast" />
  42. </view>
  43. </template>
  44. <script>
  45. export default {
  46. name: "login",
  47. data( ) {
  48. return {
  49. phoneCode: "", // 获取手机号使用的code
  50. phoneNumber: "", // 手机号
  51. access_token: "", // 用户token
  52. code: "", // authCode用户code码 ---- 登陆使用的code
  53. userInfo: "", //用户信息
  54. id: "",
  55. checkStatus: false, //协议是否勾选
  56. };
  57. },
  58. onLoad( options) {
  59. const version = wx. getSystemInfoSync(). SDKVersion;
  60. console. log( "当前版本号version", version);
  61. if ( this. compareVersion(version, "2.21.2") >= 0) {
  62. uni. removeStorageSync( "storage_USERPHONE");
  63. this. getWxCode(); // 获取微信用户code码--登录使用
  64. this. getAccessToken(); // 获取 accessToken --获取手机号使用
  65. } else {
  66. // 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
  67. wx. showModal({
  68. title: "提示",
  69. content:
  70. "当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。",
  71. });
  72. }
  73. },
  74. methods: {
  75. // 获取微信用户code码--登录使用
  76. async getWxCode( ) {
  77. const result = await wx. login();
  78. // console.log(result);
  79. if (result. code) {
  80. this. code = result. code;
  81. console. log( "登录使用的code =====>>>>>>", this. code);
  82. }
  83. },
  84. // 获取 accessToken 注意:要从服务端获取,密钥不能写在前端。 --获取手机号使用
  85. getAccessToken( ) {
  86. this. $http. getAccessToken(). then( (res) => {
  87. if (res. success) {
  88. let resObj = res. datas && res. datas. obj;
  89. console. log( "resObj======>>>>>>", resObj);
  90. this. access_token = resObj. access_token;
  91. console. log( "that.access_token======>>>>>>", this. access_token);
  92. }
  93. });
  94. },
  95. // 低版本兼容处理方法封装
  96. compareVersion( v1, v2) {
  97. v1 = v1. split( ".");
  98. v2 = v2. split( ".");
  99. const len = Math. max(v1. length, v2. length);
  100. while (v1. length < len) {
  101. v1. push( "0");
  102. }
  103. while (v2. length < len) {
  104. v2. push( "0");
  105. }
  106. for ( let i = 0; i < len; i++) {
  107. const num1 = parseInt(v1[i]);
  108. const num2 = parseInt(v2[i]);
  109. if (num1 > num2) {
  110. return 1;
  111. } else if (num1 < num2) {
  112. return - 1;
  113. }
  114. }
  115. return 0;
  116. },
  117. // 获取用户手机号-接口
  118. getUserPhone( ) {
  119. this. $http
  120. . getPhone({
  121. code: this. phoneCode,
  122. access_token: this. access_token,
  123. })
  124. . then( (res) => {
  125. // console.log("用户手机号res====>",res)
  126. if (res. success) {
  127. let resDatas = res. datas;
  128. let phoneInfo = JSON. parse(resDatas. phone_info);
  129. // console.log("获取到的用户手机号相关信息=====>>>>>>", phoneInfo)
  130. this. phoneNumber = phoneInfo. phoneNumber;
  131. console. log( "获取到的用户手机号=====>>>>>>", this. phoneNumber);
  132. uni. setStorageSync( "storage_USERPHONE", this. phoneNumber);
  133. this. login();
  134. }
  135. });
  136. },
  137. // 获取手机号的code并授权
  138. getPhoneNumber( e) {
  139. console. log( "e=====>>>>>>", e);
  140. if ( this. checkStatus) {
  141. let detail = e. detail;
  142. if (detail. errMsg === "getPhoneNumber:ok") {
  143. let that = this;
  144. this. phoneCode = detail. code;
  145. console. log( "获取手机号使用的code =====>>>>>>", this. phoneCode);
  146. if ( this. phoneCode) {
  147. this. getUserPhone();
  148. } else {
  149. this. login();
  150. }
  151. } else {
  152. console. log( "取消授权!");
  153. }
  154. } else {
  155. uni. showToast({
  156. icon: "none",
  157. title: "请阅读并确认隐私政策和用户协议",
  158. });
  159. }
  160. },
  161. // 登录
  162. async login( ) {
  163. uni. showLoading({
  164. title: "登录中.....",
  165. mask: true,
  166. });
  167. const res = await this. $http. wxLogin({
  168. code: this. code,
  169. udid: "**************",
  170. appletType: 4,
  171. });
  172. if (res. success) {
  173. if (res. datas. token) {
  174. uni. setStorageSync( "ticket", res. datas. token);
  175. }
  176. if (res. datas. obj) {
  177. uni. setStorageSync( "userInfo", res. datas. obj);
  178. this. id = res. datas. obj. extInfo. id;
  179. }
  180. this. getAppletVersion();
  181. return;
  182. }
  183. },
  184. getAppletVersion( ) {
  185. uni. hideLoading();
  186. uni. reLaunch({
  187. url: `/pages/index/index`,
  188. });
  189. },
  190. // 切换是否选中复选框
  191. changeCheckStatus( ) {
  192. this. checkStatus = ! this. checkStatus;
  193. },
  194. // 进入《隐私政策》
  195. onServiceAgreement( ) {
  196. uni. navigateTo({
  197. url: "/pages/privacy-policy/privacy-policy",
  198. fail( e) {
  199. console. log(e);
  200. },
  201. });
  202. },
  203. // 《用户协议》
  204. onUserAgreement( ) {
  205. uni. navigateTo({
  206. url: "/pages/user-service-agreement/user-service-agreement",
  207. fail( e) {
  208. console. log(e);
  209. },
  210. });
  211. },
  212. },
  213. };
  214. </script>
  215. <style lang="scss" scoped>
  216. .flex {
  217. display: flex;
  218. flex-flow: column nowrap;
  219. justify-content: flex-start;
  220. align-items: center;
  221. position: fixed;
  222. width: 100vw;
  223. height: 100vh;
  224. top: 200rpx;
  225. left: 0;
  226. padding: 0 64rpx;
  227. .title {
  228. display: flex;
  229. flex-direction: column;
  230. align-items: center;
  231. margin-bottom: 200rpx;
  232. width: 240rpx;
  233. .logo {
  234. width: 360rpx;
  235. height: 360rpx;
  236. overflow: hidden;
  237. image {
  238. width: 100%;
  239. height: auto;
  240. }
  241. text {
  242. display: inline-block;
  243. color: #404040;
  244. }
  245. }
  246. }
  247. .loginButton {
  248. width: 100%;
  249. height: 72rpx;
  250. background: linear-gradient( 142deg, #ff8677 11%, #ff424e 94%);
  251. border-radius: 88rpx;
  252. font-size: 32rpx;
  253. font-family: PingFangSC, PingFangSC-Medium;
  254. font-weight: 500;
  255. text-align: center;
  256. line-height: 52rpx;
  257. color: #ffffff;
  258. letter-spacing: 2rpx;
  259. margin-bottom: 52rpx;
  260. }
  261. .serve-rule {
  262. width: 100%;
  263. margin-left: 16rpx;
  264. display: flex;
  265. align-items: center;
  266. position: relative;
  267. .serve-label {
  268. color: #ff414e;
  269. // transform: translateX(- 10%);
  270. }
  271. .protocol-prompt {
  272. display: inline-block;
  273. position: absolute;
  274. left: 34rpx;
  275. }
  276. }
  277. .checkbox {
  278. margin-right: 0;
  279. }
  280. .row {
  281. padding: 10rpx;
  282. flex-flow: row nowrap;
  283. display: flex;
  284. justify-content: center;
  285. align-items: center;
  286. .icon-text {
  287. color: #007aff;
  288. }
  289. }
  290. .ding-row {
  291. flex-flow: row nowrap;
  292. display: flex;
  293. justify-content: center;
  294. align-items: center;
  295. .icon-text {
  296. color: #007aff;
  297. }
  298. }
  299. .icon {
  300. margin-right: 10rpx;
  301. display: flex;
  302. align-items: center;
  303. }
  304. .btn {
  305. width: 90%;
  306. overflow: hidden;
  307. text-align: center;
  308. }
  309. }
  310. </style>


转载:https://blog.csdn.net/weixin_48594833/article/details/128685560
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场