微信小程序登录获取用户openid,获取昵称、头像、手机号授权

发布于:2025-02-23 ⋅ 阅读:(120) ⋅ 点赞:(0)

前端小程序代码

  1. app.js
// app.js
App({
  onLaunch() {
    // 展示本地存储能力
    const logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)

    // 登录
    wx.login({
      timeout: 5000,
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId4
        console.log("res: ", res)
        if (res.code) {
          wx.request({
            url: "https://xxxxxxxxx.cn/api/wxLogin",
            data: {
              code: res.code
            },
          })
        }
      },
      fail: res => {
        console.log("fail: ", res)
      }
    })
  },
  globalData: {
    userInfo: null
  }
})
  1. index.wxml
<!--index.wxml-->
<scroll-view class="scrollarea" scroll-y type="list">
  <view class="container">
    <view class="userinfo">
      <block wx:if="{{canIUseNicknameComp && !hasUserInfo}}">
        <button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
          <image class="avatar" src="{{userInfo.avatarUrl}}"></image>
        </button>
        <view class="nickname-wrapper">
          <text class="nickname-label">昵称</text>
          <input type="nickname" class="nickname-input" placeholder="请输入昵称" bind:change="onInputChange" />
        </view>
        <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">
          <text wx:if="{{ userInfo.phoneNumber == '' }}">手机号授权</text>
          <text wx:else>{{ userInfo.phoneNumber }}</text>
        </button>
      </block>
      <block wx:elif="{{!hasUserInfo}}">
        <button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button>
        <view wx:else> 请使用2.10.4及以上版本基础库 </view>
      </block>
      <block wx:else>
        <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
        <text class="userinfo-nickname">{{userInfo.nickName}}</text>
        <text class="userinfo-nickname">{{userInfo.phoneNumber}}</text>
      </block>
    </view>
    <view class="usermotto">
      <text class="user-motto">{{motto}}</text>
    </view>
  </view>
</scroll-view>
  1. index.js
// index.js
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'

Page({
  data: {
    motto: 'Hello World',
    userInfo: {
      avatarUrl: defaultAvatarUrl,
      nickName: '',
      phoneNumber: "",
    },
    hasUserInfo: false,
    canIUseGetUserProfile: wx.canIUse('getUserProfile'),
    canIUseNicknameComp: wx.canIUse('input.type.nickname'),
  },
  bindViewTap() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onChooseAvatar(e) {
    console.log(e.detail)
    const { avatarUrl } = e.detail
    const { nickName, phoneNumber } = this.data.userInfo
    this.setData({
      "userInfo.avatarUrl": avatarUrl,
      hasUserInfo: nickName && phoneNumber && avatarUrl && avatarUrl !== defaultAvatarUrl,
    })
  },
  onInputChange(e) {
    const nickName = e.detail.value
    const { avatarUrl, phoneNumber } = this.data.userInfo
    this.setData({
      "userInfo.nickName": nickName,
      hasUserInfo: nickName && phoneNumber && avatarUrl && avatarUrl !== defaultAvatarUrl,
    })
  },
  getPhoneNumber(e) {
    const { nickName, avatarUrl } = this.data.userInfo
    wx.request({
      // url: "http://127.0.0.1:5000/api/gePhone",
      url: "https://xxxxxxxxxxx.cn/api/gePhone",
      data: {
        code: e.detail.code
      },
      success: res => {
        // 请求成功时的回调
        console.log("请求成功:", res);
        // 在这里解析返回的数据
        const phoneNumber = res.data.phone_info.phoneNumber
        this.setData({
          "userInfo.phoneNumber": phoneNumber,
          hasUserInfo: nickName && phoneNumber && avatarUrl && avatarUrl !== defaultAvatarUrl,
        })
      },  
    })
  },
  getUserProfile(e) {
    // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
    wx.getUserProfile({
      desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
      success: (res) => {
        console.log(res)
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    })
  },
})

后端python代码

import requests
from flask import Flask, request, jsonify


app = Flask(__name__)
appid = "xxxxxxxxx"
secret = "xxxxxxxxxxxxxxxxxxxxxxx"


@app.route("/api")
def index():
    return jsonify({"msg": "Hello, World!"})


@app.route('/api/wxLogin')
def wx_login():
    """微信小程序登录"""
    # 获取前端get请求的参数
    code = request.args.get('code')
    print(code)

    # 前端通过wx.login获取临时登录凭证code, 拿到会话秘钥session_key和用户唯一表示openid
    res = requests.get(url="https://api.weixin.qq.com/sns/jscode2session", params={
        "appid": appid,
        "secret": secret,
        "js_code": code,
        "grant_type": "authorization_code",
    })
    print(res.json())
    return code


@app.route("/api/gePhone")
def get_phone():
    """获取用户手机号"""
    # 获取token
    # access_token: 获取到的凭证, expires_in: 凭证有效时间,单位:秒。目前是7200秒之内的值。
    res = requests.get(url="https://api.weixin.qq.com/cgi-bin/token", params={
        "grant_type": "client_credential",
        "appid": appid,
        "secret": secret,
    })
    print(res.json())
    # 获取前端手机号授权获取的code
    code = request.args.get('code')
    # 获取手机号
    res = requests.post(url=f"https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={res.json()['access_token']}", json={
        "code": code,
    })
    print(res.json())
    return jsonify(res.json())


if __name__ == '__main__':
    app.run()

效果

在这里插入图片描述
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/07f18586652a401ca591947c00f70083.png
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到