草庐IT

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

前端菜菜DayDayUp 2023-04-04 原文

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

一、

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

这是服务端的

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

 

 注意:

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

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

二、

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

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

 

个人使用时碰到的坑:

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

详细实现代码:

<template>
  <view class="flex">
    <view class="title">
      <view class="logo">
        <image src="/static/image/logo.png" mode="widthFix" />
      </view>
    </view>
    <!-- 手机号登录  --授权并获取手机号保存至本地 -->
    <button
      type="default"
      class="loginButton"
      open-type="getPhoneNumber"
      @getphonenumber="getPhoneNumber"
    >
      <view class="row">
        <view class="icon">
          <u-icon name="weixin-fill" size="28"></u-icon>
        </view>
        <view style="font-size: 30rpx">微信登录</view>
      </view>
    </button>
    <!-- 协议选择 -->
    <view class="serve-rule">
      <u-checkbox-group size="24" @click="changeCheckStatus">
        <u-checkbox
          class="checkbox"
          v-model="checkStatus"
          activeColor="#ff414e"
        ></u-checkbox>
      </u-checkbox-group>
      <view class="protocol-prompt">
        <text @click="changeCheckStatus">本人理解并同意</text>
        <text class="serve-label" @click.stop="onServiceAgreement"
          >《隐私政策》</text
        >
        <text class="serve-label" @click.stop="onUserAgreement"
          >《用户协议》</text
        >
      </view>
    </view>
    <u-toast ref="uToast" />
  </view>
</template>

<script>
export default {
  name: "login",
  data() {
    return {
      phoneCode: "", // 获取手机号使用的code
      phoneNumber: "", // 手机号
      access_token: "", // 用户token

      code: "", // authCode用户code码  ---- 登陆使用的code
      userInfo: "", //用户信息
      id: "",
      checkStatus: false, //协议是否勾选
    };
  },
  onLoad(options) {
    const version = wx.getSystemInfoSync().SDKVersion;
    console.log("当前版本号version", version);
    if (this.compareVersion(version, "2.21.2") >= 0) {
      uni.removeStorageSync("storage_USERPHONE");
      this.getWxCode(); // 获取微信用户code码--登录使用
      this.getAccessToken(); // 获取 accessToken --获取手机号使用
    } else {
      // 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
      wx.showModal({
        title: "提示",
        content:
          "当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。",
      });
    }
  },
  methods: {
    // 获取微信用户code码--登录使用
    async getWxCode() {
      const result = await wx.login();
      // console.log(result);
      if (result.code) {
        this.code = result.code;
        console.log("登录使用的code =====>>>>>>", this.code);
      }
    },
    // 获取 accessToken 注意:要从服务端获取,密钥不能写在前端。 --获取手机号使用
    getAccessToken() {
      this.$http.getAccessToken().then((res) => {
        if (res.success) {
          let resObj = res.datas && res.datas.obj;
          console.log("resObj======>>>>>>", resObj);
          this.access_token = resObj.access_token;
          console.log("that.access_token======>>>>>>", this.access_token);
        }
      });
    },
    // 低版本兼容处理方法封装
    compareVersion(v1, v2) {
      v1 = v1.split(".");
      v2 = v2.split(".");
      const len = Math.max(v1.length, v2.length);

      while (v1.length < len) {
        v1.push("0");
      }
      while (v2.length < len) {
        v2.push("0");
      }

      for (let i = 0; i < len; i++) {
        const num1 = parseInt(v1[i]);
        const num2 = parseInt(v2[i]);

        if (num1 > num2) {
          return 1;
        } else if (num1 < num2) {
          return -1;
        }
      }
      return 0;
    },
    // 获取用户手机号-接口
    getUserPhone() {
      this.$http
        .getPhone({
          code: this.phoneCode,
          access_token: this.access_token,
        })
        .then((res) => {
          // console.log("用户手机号res====>",res)
          if (res.success) {
            let resDatas = res.datas;
            let phoneInfo = JSON.parse(resDatas.phone_info);
            // console.log("获取到的用户手机号相关信息=====>>>>>>", phoneInfo)
            this.phoneNumber = phoneInfo.phoneNumber;
            console.log("获取到的用户手机号=====>>>>>>", this.phoneNumber);
            uni.setStorageSync("storage_USERPHONE", this.phoneNumber);
            this.login();
          }
        });
    },
    // 获取手机号的code并授权
    getPhoneNumber(e) {
      console.log("e=====>>>>>>", e);
      if (this.checkStatus) {
        let detail = e.detail;
        if (detail.errMsg === "getPhoneNumber:ok") {
          let that = this;
          this.phoneCode = detail.code;
          console.log("获取手机号使用的code =====>>>>>>", this.phoneCode);
          if (this.phoneCode) {
            this.getUserPhone();
          } else {
            this.login();
          }
        } else {
          console.log("取消授权!");
        }
      } else {
        uni.showToast({
          icon: "none",
          title: "请阅读并确认隐私政策和用户协议",
        });
      }
    },
    // 登录
    async login() {
      uni.showLoading({
        title: "登录中.....",
        mask: true,
      });
      const res = await this.$http.wxLogin({
        code: this.code,
        udid: "**************",
        appletType: 4,
      });
      if (res.success) {
        if (res.datas.token) {
          uni.setStorageSync("ticket", res.datas.token);
        }
        if (res.datas.obj) {
          uni.setStorageSync("userInfo", res.datas.obj);
          this.id = res.datas.obj.extInfo.id;
        }
        this.getAppletVersion();
        return;
      }
    },
    getAppletVersion() {
      uni.hideLoading();
      uni.reLaunch({
        url: `/pages/index/index`,
      });
    },
    // 切换是否选中复选框
    changeCheckStatus() {
      this.checkStatus = !this.checkStatus;
    },
    // 进入《隐私政策》
    onServiceAgreement() {
      uni.navigateTo({
        url: "/pages/privacy-policy/privacy-policy",
        fail(e) {
          console.log(e);
        },
      });
    },
    // 《用户协议》
    onUserAgreement() {
      uni.navigateTo({
        url: "/pages/user-service-agreement/user-service-agreement",
        fail(e) {
          console.log(e);
        },
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.flex {
  display: flex;
  flex-flow: column nowrap;
  justify-content: flex-start;
  align-items: center;
  position: fixed;
  width: 100vw;
  height: 100vh;
  top: 200rpx;
  left: 0;
  padding: 0 64rpx;

  .title {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 200rpx;
    width: 240rpx;

    .logo {
      width: 360rpx;
      height: 360rpx;
      overflow: hidden;

      image {
        width: 100%;
        height: auto;
      }

      text {
        display: inline-block;
        color: #404040;
      }
    }
  }

  .loginButton {
    width: 100%;
    height: 72rpx;
    background: linear-gradient(142deg, #ff8677 11%, #ff424e 94%);
    border-radius: 88rpx;
    font-size: 32rpx;
    font-family: PingFangSC, PingFangSC-Medium;
    font-weight: 500;
    text-align: center;
    line-height: 52rpx;
    color: #ffffff;
    letter-spacing: 2rpx;
    margin-bottom: 52rpx;
  }

  .serve-rule {
    width: 100%;
    margin-left: 16rpx;
    display: flex;
    align-items: center;
    position: relative;

    .serve-label {
      color: #ff414e;
      // transform: translateX(-10%);
    }
    .protocol-prompt {
      display: inline-block;
      position: absolute;
      left: 34rpx;
    }
  }

  .checkbox {
    margin-right: 0;
  }

  .row {
    padding: 10rpx;
    flex-flow: row nowrap;
    display: flex;
    justify-content: center;
    align-items: center;

    .icon-text {
      color: #007aff;
    }
  }

  .ding-row {
    flex-flow: row nowrap;
    display: flex;
    justify-content: center;
    align-items: center;

    .icon-text {
      color: #007aff;
    }
  }

  .icon {
    margin-right: 10rpx;
    display: flex;
    align-items: center;
  }

  .btn {
    width: 90%;
    overflow: hidden;
    text-align: center;
  }
}
</style>

有关微信小程序 - 实现手机号登录--授权并获取手机号保存至本地的更多相关文章

  1. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  2. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  3. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  4. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  5. 怎样用一台手机做自媒体? - 2

    其实做自媒体的成本并不高,入门只需要一部手机即可!在手机上找视频素材、使用手机剪辑视频、最后使用手机发布视频作品获得收益!方法并不难,今天这期内容就来给粉丝们分享一种小方法,每天稳定收益100-300,抓紧点赞收藏!1、找素材(1)使用手机拍摄自己喜欢的经典段落,使用程序把文案内容提取出来(2)也可以在豆瓣、知乎、微博等网站中找一些自己需要的文案素材(3)把文案进行润色修改,可以加入一些自己的观点(4)视频素材可以使用软件中自带的素材,也可以在素材网站中下载完整版的素材2、文案配音(1)把复制好的文案直接导入小程序中(2)调整音色、音调后一键合成音频即可(3)可以选择自己朗读配音,需要花一点时

  6. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  9. 微信小程序通过字典表匹配对应数据 - 2

    前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立

  10. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

随机推荐