微信小程序端用户授权处理

栏目: IOS · Android · 发布时间: 5年前

taro

1.安装 tarojs

npm install -g @tarojs/cli

2.初始化项目

taro init taro-login

3.进入目录

cd taro-login

4.运行编译

npm run dev:weapp

5.修改文件 /src/app.js 代码

...

class App extends Component {

  config = {
    pages: [
      'pages/user/user', // new
      'pages/index/index',
    ],

6.微信登录需求

如果我们需要用户一进入就取得用户的授权,以便于进行某些记录用户信息的操作,而微信又要求用户去点页面上的某个按钮才能获取信息,那怎么办呢?只能把一个按钮放在用户不能不点的地方,那就只有弹窗了。微信 wx.showModal 不能满足我们的需求,只能自己造一个,在用户第一次进来的时候弹窗,再次进来的时候则不显示。为了让这个组件具有拓展性,我们根据传入的值来修改 确认 位置按钮的属性,如果是授权的弹窗就改按钮属性为 openType='getUserInfo' 。(摘自 Taro 多端开发实现原理与项目实战 )

7.新建文件夹和modal.js文件 /src/components/modal/modal.js

import Taro, { Component } from '@tarojs/taro'
import { View, Button } from '@tarojs/components'

import './modal.scss'

class Modal extends Component {
  constructor() {
    super(...arguments)
    this.state = {}
  }

  onConfirmClick = () => {
    this.props.onConfirmCallback()
  }

  onCancelClick = () => {
    this.props.onCancelCallback()
  }

  onAuthConfirmClick = (e) => {
    this.props.onConfirmCallback(e.detail)
  }

  preventTouchMove = (e) => {
    e.stopPropagation()
  }

  render() {
    const { title, contentText, cancelText, confirmText, isAuth } = this.props
    return (
      <View className='toplife_modal' onTouchMove={this.preventTouchMove}>
        <View className='toplife_modal_content'>
          <View className='toplife_modal_title'>{title}</View>
          <View className='toplife_modal_text'>{contentText}</View>
          <View className='toplife_modal_btn'>
            <Button className='toplife_modal_btn_cancel' onClick={this.onCancelClick}>{cancelText}</Button>
            {!isAuth ?
              <Button className='toplife_modal_btn_confirm' onClick={this.onConfirmClick}>{confirmText}</Button> :
              <Button className='toplife_modal_btn_confirm' openType='getUserInfo' onGetUserInfo={this.onAuthConfirmClick}>授权</Button>}
          </View>
        </View>
      </View>
    )
  }
}

Modal.defaultProps = {
  title: '',
  contentText: '',
  cancelText: '取消',
  confirmText: '确定',
  isAuth: false,
  onCancelCallback: () => { },
  onConfirmCallback: () => { }
}

export default Modal

Modal 组件还算比较简单,组件的属性:

字段 说明
title 提示的标题
contentText 提示的描述
cancelText 取消按钮的文案
cancelCallback 取消回调的函数
confirmText 确认按钮的文案
confirmCallback 确认回调函数
isAuth 标记是否为授权按钮

在内部设置了一个函数 preventTouchMove ,其作用是弹窗出现蒙层的时候,阻止在蒙版上的滑动手势 onTouchMove 。另外一个函数 authConfirmClick , 当 isAuth 为真时,确认按钮为取得个人信息的授权按钮,此时把个人信息当值传递给调用的函数。(摘自 Taro 多端开发实现原理与项目实战 )

8.添加 modal.scss 文件

/*postcss-pxtransform rn eject enable*/

.toplife_modal {
  position: fixed;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  background-color: rgba(0, 0, 0, .8);
  z-index: 100;

  &_content {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 600px;
    height: 320px;
    transform: translate(-50%, -50%);
    background-color: #fff;
    color: #232321;
    text-align: center;
    border-radius: 30px;
  }

  &_title {
    margin-top: 40px;
    font-size: 32px;
  }

  &_text {
    margin-top: 40px;
    font-size: 24px;
  }

  &_btn {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 88px;
    border-top: 2px solid #eee;

    &_cancel {
      color: #8c8c8c;
      border-radius: 0;
      border: 0;
      border-right: 2px solid #eee;
      border-bottom-left-radius: 30px;
    }

    &_confirm {
      color: #666;
      border-radius: 0;
      border: 0;
      border-bottom-right-radius: 30px;
    }

    button {
      display: block;
      float: left;
      width: 50%;
      height: 88px;
      text-align: center;
      line-height: 88px;
      font-size: 32px;
      box-sizing: border-box;
      background-color: #fff;

      &::after {
        border: 0;
      }
    }
  }
}

9.新建文件 /src/page/user/user.js ,在 user.js 中引用该 Modal 组件

import Taro, { Component } from '@tarojs/taro';
import { View, Image, Text } from '@tarojs/components';
import classnames from 'classnames'
import Modal from '../../components/modal/modal';
import { setGlobalData } from '../../utils/globalData';
import { getUserInfo, getIsAuth } from '../../utils/getUser';


class Info extends Component {
  config = {
    navigationBarTitleText: 'TARO商城',
    enablePullDownRefresh: true,
    backgroundTextStyle: 'dark',
    disableScroll: true
  }

  constructor() {
    super(...arguments)
    this.state = {
      animationClass: '',
      showAuthModal: false,
      shouldIndexHidden: false,
    }
    this.env = process.env.TARO_ENV
  }
  hideAuthModal() {
    this.setState({
      showAuthModal: false
    })
    Taro.setStorage({ key: 'isHomeLongHideAuthModal', data: true })
  }

  onProcessAuthResult = (userData) => {
    Taro.setStorage({ key: 'isHomeLongHideAuthModal', data: true })
    if (userData.userInfo) {
      setGlobalData('userData', userData)
    }
    this.setState({
      showAuthModal: false
    })
    getIsAuth()
  }

  async onPullDownRefresh() {
    if (this.state.shouldIndexHidden) {
      Taro.stopPullDownRefresh() // 停止下拉刷新
    } else {
      await this.props.onFetchIndexList()
      Taro.stopPullDownRefresh() // 停止下拉刷新
    }
  }

  componentDidMount() {
    if (this.env === 'weapp') {
      // 用类名来控制动画
      setTimeout(async () => {
        const userData = await getUserInfo();
        Taro.getStorage({
          key: 'isHomeLongHideAuthModal',
          success: (res) => {
            const isHomeLongHideAuthModal = res.data;
            let showAuthModal
            if (!userData && !this.state.showAuthModal && !isHomeLongHideAuthModal) {
              showAuthModal = true
            } else {
              showAuthModal = false
            }
            this.setState({
              animationClass: 'animation',
              showAuthModal
            })
          },
          fail: () => {
            let showAuthModal
            if (!userData && !this.state.showAuthModal) {
              showAuthModal = true
            } else {
              showAuthModal = false
            }
            this.setState({
              animationClass: 'animation',
              showAuthModal
            })
          }
        })
      }, 1000)
      getIsAuth()
    } else if (this.env === 'h5' || this.env === 'rn') {
      console.log('h5登录')
    }
  }
  render() {
    const { animationClass, shouldIndexHidden, showAuthModal } = this.state
    const { loginname, avatar_url } = this.props;
    const indexClassNames = classnames('container', 'index', animationClass, {
      hidden: shouldIndexHidden
    })
    return (
      <View className={indexClassNames}>
        <View className='login-head'>
          <Image className='login-head-back'
            src={require('../../assets/img/loginBack.jpg')}
          />
          <Image className='login-head-head'
            src={avatar_url ? avatar_url : require('../../assets/img/head.png')}
          />
          {loginname ? <Text classnames='login-head-name'>{loginname}</Text> : null}
        </View>
        {showAuthModal && <Modal
          title='授权提示'
          contentText='诚邀您完成授权,尊享畅游体验'
          onCancelCallback={this.hideAuthModal.bind(this)}
          onConfirmCallback={this.onProcessAuthResult.bind(this)}
          isAuth
        />}
      </View>
    )
  }
}

export default Info
我们是如何保证这个应用只有一次授权弹窗呢? 关键代码是 Taro.setStorageSync('isHomeLongHideAuthModal', true) ,如果弹出了一次,就在本地存一个标记已经弹过授权框,下一次弹窗之前可以根据此判断。

至此我们完成了授权处理,但如果可以的话还是要优雅一些,在需要的时候才征求用户授权,保证用户体验。(摘自 Taro 多端开发实现原理与项目实战 )

10.新建几个辅助文件

/src/utils/globalData.js

const globalData = {}

export function setGlobalData(key, val) {
  globalData[key] = val
}

export function getGlobalData(key) {
  return globalData[key]
}

/src/utils/request.js

import Taro from '@tarojs/taro';
import '@tarojs/async-await';

export function getJSON(url, data) {
  Taro.showLoading();
  return Taro.request({ url: url, data: data, method: 'GET' }).then(result => {
    Taro.hideLoading();
    return result;
  })
}

export function postJSON(url, data) {
  Taro.showLoading()
  return Taro.request({
    header: { 'content-type': 'application/json' },
    url: url,
    data: data,
    method: 'POST'
  }).then(result => {
    Taro.hideLoading();
    return result;
  });

}

/src/constants/api

const rootPath = 'http://127.0.0.1:5000/v1';
const apiObject = {
  registerclient: rootPath + '/client/register', //注册用户
  getusertoken: rootPath + '/token', // 登录成功之后获取用户token
  checkusertoken: rootPath + '/token/secret', //验证用户token
  getuserinfo: rootPath + '/user', //获取用户信息
}
export default apiObject;

11. 新建一个登录获取token的函数

/src/utils/getUser.js

import Taro from '@tarojs/taro'
import { getGlobalData } from './globalData'
import api from '../constants/api';
import { postJSON } from '../utils/request';


async function getUserInfo() {
  const userData = getGlobalData('userData')
  if (userData) {
    return userData
  }
  try {
    const _userData = await Taro.getUserInfo()
    return _userData
  } catch (err) {
    console.log(err)
    console.log('微信登录或用户接口故障')
    return null
  }
}

async function getIsAuth() {
  const loginRes = await Taro.login()
  let { userInfo } = await getUserInfo()
  let isAuth = false
  if (userInfo) {

    // 使用微信注册新用户
    let result = await postJSON(api.registerclient, {
      "avatar": userInfo.avatarUrl,
      "sex": userInfo.gender,
      "nickname": userInfo.nickName,
      "account": loginRes.code,
      "type": 200
    });
    if (result.data.error_code == 0) {

      // 登录用户,获取token,缓存到前端
      const tokenRes = await Taro.login()
      let auth_token = await postJSON(api.getusertoken, {
        "account": tokenRes.code,
        "type": 200
      })
      if (auth_token.statusCode == 201) {
        Taro.setStorage({ key: 'token', data: auth_token.data.token })// 设置到缓存
        Taro.showToast({ title: '授权成功' })
        userInfo.isAuth = true
        isAuth = true
      }
    } else {
      Taro.showToast({ title: '授权失败,请稍后再试', icon: 'none' })
    }

  } else {
    userInfo = {
      isAuth: false
    }
  }
  console.log('isAuth: ', isAuth)
  return isAuth
}

export {
  getUserInfo,
  getIsAuth
}

flask

学习资料:


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Security, Privacy and Commerce, 2nd Edition

Web Security, Privacy and Commerce, 2nd Edition

Simson Garfinkel / O'Reilly Media / 2002-01-15 / USD 44.95

Since the first edition of this classic reference was published, World Wide Web use has exploded and e-commerce has become a daily part of business and personal life. As Web use has grown, so have ......一起来看看 《Web Security, Privacy and Commerce, 2nd Edition》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具