Taro框架实现微信登录及获取手机号和用户信息

当前文章收录状态:
查询中...
import React , { useState } from "react";
import { Button, Image, Toast } from "@taroify/core";
import Taro from "@tarojs/taro";
import wechatApi from "../api/wechat";
import WXBizDataCrypt from "../utils/WXBizDataCrypt";

function WechatLoginComponent() {
  const [fail, failState] = useState(false);
  const [failText, failTextState] = useState("错误提示");
  const [dialogType, dialogTypeState] = useState("fali");
  const [phone, phoneState] = useState("");
  const [userInfo, userInfoState] = useState({});
  const style = {
    width: "100%",
    height: "100%",
  };
  const getUserProfile = () => {
    Taro.getUserProfile({
      desc: '用户登录', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
      success: (res) => {
        userInfoState(res.userInfo);
      }
    });
  };
  const getPhonenNmber = (e) => {
    const iv = e.detail.iv;
    const encryptedData = e.detail.encryptedData;
    // 登录
    Taro.login({
      success: function (res) {
        if (res.code) {
          // 获取用户唯一id
          wechatApi.jscode2session(res.code).then((r) => {
            if (r.statusCode == 200) {
              // 获取用户openid和session_key
              const { openid, session_key } = r.data;
              // 获取手机号
              const pc = new WXBizDataCrypt("wx339df4bd91fecc8d", session_key);
              const data = pc.decryptData(encryptedData , iv);
              const phoneNumber = data.phoneNumber;
              Taro.setStorage({
                key: "phoneNumber",
                data: phoneNumber
              })
              phoneState(phoneNumber);
              // 储存用户唯一openid到后端

              // 提示登录成功
              errorDialog("登录成功", "success");
            }
          });
        } else {
          errorDialog('登录失败!' + res.errMsg, "fail");
        }
      }
    });
  };
  const errorDialog = (text, type) => {
    failState(true);
    failTextState(text);
    dialogTypeState(type);
    setTimeout(() => {
      failState(false);
    }, 1000);
  }
  return (
    <>
      <Toast open={fail} type={dialogType}>{failText}</Toast>
      <Image style={{ width: "100px", height: "100px" }} src={userInfo.avatarUrl} />
      <p>昵称:{userInfo.nickName}</p>
      <p>手机号:{phone}</p>
      <Button color='primary' shape='round' style={style} open-type='getPhoneNumber' onGetPhoneNumber={getPhonenNmber}>
        一键登录
      </Button>
      <Button color='primary' shape='round' style={style} onClick={getUserProfile}>
        一键获取信息
      </Button>
    </>
  );
}

export default WechatLoginComponent;

手机号解密文件WXBizDataCrypt.ts

import { createDecipheriv } from 'crypto'

class WXBizDataCrypt {
  constructor(appId, sessionKey) {
    this.appId = appId
    this.sessionKey = sessionKey
  }
  decryptData(encryptedData, iv) {
    // base64 decode
    var sessionKey = new Buffer(this.sessionKey, 'base64')
    encryptedData = new Buffer(encryptedData, 'base64')
    iv = new Buffer(iv, 'base64')

    try {
      // 解密
      var decipher = createDecipheriv('aes-128-cbc', sessionKey, iv)
      // 设置自动 padding 为 true,删除填充补位
      decipher.setAutoPadding(true)
      var decoded = decipher.update(encryptedData, 'binary', 'utf8')
      decoded += decipher.final('utf8')

      decoded = JSON.parse(decoded)

    } catch (err) {
      throw new Error('Illegal Buffer')
    }

    if (decoded.watermark.appid !== this.appId) {
      throw new Error('Illegal Buffer')
    }

    return decoded
  }
}

export default WXBizDataCrypt
© 版权声明
THE END
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=270198dipw4ko
点赞7赞赏 分享
评论 共1条

请登录后发表评论