项目实践 | Uniapp微信登录

528 阅读2分钟

概述

  • 如果未登录则引导用户进行登录操作。
  • 首次登录需要授权(获取微信头像和昵称等)并保存。
  • 在登录成功后,保存用户身份信息到全局状态。
  • 在随后的 http 请求中都需要携带用户身份信息。

(1)判断登录状态

全局状态里有值? uni.getStorageSync('isLogged')

未登录则跳转到登录页 uni.reLaunch({

onLaunch: function() {
    // 获取用户登录状态
    const isLogged = uni.getStorageSync('isLogged');
    if (!isLogged) {
      // 用户未登录,跳转到登录页
      uni.reLaunch({
        url: '/pages/login/login'
      });
		}
	},
},

(2)引导用户进行授权

  • 一个状态变量表示登录次数setStorageSync('login_num',1),首次登录则弹出授权窗口
  • 授权,如 open-type="chooseAvatar"
  • 监听授权窗口的头像和昵称变化,对其进行一定处理(如头像转 base64)
  • 将授权信息保存为全局状态,如setStorageSync(avatar_url,xxxx),以备后用
<template>
  <!-- 初始登录按钮 -->
  	<button @click="authLogin">微信授权登录</button>
  <!-- 授权窗口 -->
  <!-- 以获取头像为例 -->
    <button class="avatar-wrapper" 
      open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
      <image class="avatar" :src="avatarUrl"></image>
    </button>
    <view @tap.stop="wxGetUserProfile">保存</view>
</template>
<script>
   methods: {
     	//首次授权,出现授权弹框,授权完成后点确定后登录
			authLogin() {
				if (this.isFrist == 1) {
					this.isAuth = true;
				//非首次,则不出现弹框,直接登录
				} else {
					this.isAuth = false;
					this.wxGetUserProfile();
				}
			},
      //监听头像变化事件
      onChooseAvatar(e) {
          let _this = this;
          //将微信返的临时图片转为base64格式图
          pathToBase64(e.detail.avatarUrl).then(base64 => {
            this.avatarUrl = base64;
            uni.setStorageSync('avatar_url',base64); 
          })
      }, 
  }
</script>

(3)登录过程

  • 根据 appid 获取 code ---> uni.login 的 sucess 回调里获取( res.code

  • 客户端向服务器发送 code

  • 服务器用 code 和 appid,去微信接口服务获取 session_keyopen_id 并返回

  • 客户端

    • 更新登录状态 isLogged
    • 保存身份信息 session_key(token)open_id(用户 id)
  • 有了身份信息后,客户端就可以开始跟服务器合法通信了,只需要:getStorageSync 出来上述身份信息,然后将其携带在后续所有的 http 里

//微信登录接口
wxGetUserProfile() {
  //...其他和登录次数有关逻辑
  //
  let code = '';
  uni.login({
    provider: 'weixin',
    success: (res) => {		
      code = res.code; //step1:根据appid获取code
      
      _this.loginToServer(code); //step2:客户端发送code
        
    },
    fail: (err) => {
      console.error(err);
    }
  });
  
},
loginToServer(code){
    let _this = this;
    console.log("code=",code)
    uni.request({
      url: 'http://54.89.242.79:8001/authorize',
      method: 'POST',
      data: {
        code:code,
        //其他 
      },
      success: (res) => {
        console.log(res.data.status)
        if (res.data.status === "success") {
          
          // step3: 登录成功,拿到服务端给的session_key和open_id
          let open_id = res.data.data.open_id;
          let session_key = res.data.data.session_key;
  
          //step4:更新并保持登录态
          uni.setStorageSync('isLogged', true);
          uni.setStorageSync('open_id', open_id);
          uni.setStorageSync('session_key', session_key);
          
          // step5:授权后上传user_name等用户信息
          setTimeout(() => {
            _this.updateUsername(open_id,session_key);
          },5000)         
        } else {
          console.log(res.data.msg)
        }
      },
      fail: (err) => {
        console.error(err);
      }
    });
  },

(4) 更新服务端的 用户信息(如头像和昵称)

把授权信息,发给服务器让它更新(以用户名为例)

//更新用户信息
updateUsername(open_id,session_key){
    let user_name = uni.getStorageSync('user_name');
    uni.request({
      url: 'http://xxxx:8001/updateUserInfo',
      method: 'POST',
      data: {
        open_id:open_id, 
        session_key:session_key, 
        user_name:user_name
      },
      success: (res) => {		
        // 跳转至首页
        uni.reLaunch({
          url: '/pages/index/index'
        });		
      },
      fail: (err) => {
        console.error(err);
      }
    });
    
  }
//获取用户信息
uni.request({
  url: 'http://xxxx:8001/getUserInfo',
  method: 'POST',
  header: {
    'Content-Type': 'application/json'
  },
  data: {
    open_id:open_id, 
    session_key:session_key
  },
  success: (res) => {
    if (res.data.status === "success") {
      _this.user_name = res.data.data.user_name; 
    } else {
    }
  },
  fail: (err) => {
    console.error(err);
  }
  });