频道栏目
首页 > 资讯 > 微信小程序 > 正文

微信小程序端用户授权处理-教程-小程序社区-微信小程序-微信小程序开发社区-小程序开发论坛-微信小程序联盟

19-03-07        来源:[db:作者]  
收藏   我要投稿

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

学习资料:

  • 慕课网-Python Flask构建可扩展的RESTful API
  • 慕课网-掌握Taro多端框架 快速上手小程序/H5开发
  • Taro 多端开发实现原理与项目实战
    赞赏
相关TAG标签
上一篇:从前端程序员的视角看小程序的稳定性保障-教程-小程序社区-微信小程序-微信小程序开发社区-小程序开发论坛-微信小程序联盟
下一篇:小程序开发之影分身术-教程-小程序社区-微信小程序-微信小程序开发社区-小程序开发论坛-微信小程序联盟
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站