mpvue入坑之旅(四) 微信登录

1 小程序登录

详见 开发者文档

1)调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
2)调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key。

前台(获取登录凭证code):

wx.login({
  success(res) {
    if (res.code) {
      that.$http.post(
        '/wx/login', res
      ).then(resData => {
        console.log(resData)
      })
    }
  }
})

后台(换取openId和session_key):

public WXLoginResult authCode2Session(WXLoginParam wxLoginParam) {
	StringBuffer param = new StringBuffer();
	param.append("appid=" + WxConstant.APP_ID);
	param.append("&secret=" + WxConstant.APP_SECRET);
	param.append("&js_code=" + wxLoginParam.getCode()); // 从前端获取code
	param.append("&grant_type=authorization_code"); // 默认值

	WXLoginResult result = new WXLoginResult();
	try {
		String resultStr = HttpUtil.sendGet("https://api.weixin.qq.com/sns/jscode2session", param.toString());// 返回openid和session_key
		Boolean resultBool = StringUtils.isNotBlank(resultStr);
		if (resultBool) {
			result = JSON.parseObject(resultStr).toJavaObject(WXLoginResult.class);
		}
		return result;
	} catch (Exception e) {
		log.error("请求微信授权GET请求出现异常!", e);
		return result;
	}
}

2 根据token获取用户信息

1) /wx/login 接口,后台将用户信息保存在Redis中,key为token
2)前台保存token到本地

wx.setStorageSync('token', token)

3)在request请求头部传递token,后台即可根据token获取用户信息

function request(url, method, data, header = {}) {
  wx.showLoading({
    title: '加载中'
  })
  return new Promise((resolve, reject) => {
    wx.request({
      url: apiUrl + url,
      method: method,
      data: data,
      headers: {
        'token': wx.getStorageSync('token'),
        'content-type': 'application/json' // 默认转为json格式
      },
      success: function(res) {
        wx.hideLoading()
        resolve(res.data)
      },
      fail: function(res) {
        wx.hideLoading()
        reject(res.data)
      },
      complete: function() {
        wx.hideLoading()
      }
    })
  })
}

3 token过期

官方文档中,token有效期是2小时,所以可以1小时后重新获取一次token,以防过期

//保存token时,顺便保存tokenTime
wx.setStorageSync('tokenTime', new Date().getTime())

//1小时更新
let tokenTime = wx.getStorageSync("tokenTime");
if (tokenTime == null || new Date().getTime() - tokenTime > 1000 * 60 * 60){
  that.login()
}

4 实例

1)project.config.json中的AppId要与后台使用的一致
2)pages下新增页面 mine (main.js代码与其他页面一样)
在这里插入图片描述

  1. 增加登录按钮,调用小程序原生的open-type以唤起授权弹窗,编写对应登录方法
  2. 页面加载时,检查用户授权信息

index.vue 代码:

<template>
  <div class="userinfo" >
    <img class="userinfo-avatar" src="{{userInfo.avatarUrl?userInfo.avatarUrl:'/static/images/user.png'}}" background-size="cover" />
    
    <button open-type="getUserInfo" @getuserinfo= "getUserInfo" @click="login">{{userInfo.nickName?userInfo.nickName:'登录'}}</button>
  </div>
</template>

<script>

export default {
  data () {
    return {
      userInfo: {}
    }
  },

  methods: {
    getUserData () {
      var that = this
      wx.getSetting({
        success: function (res) {
          console.log(res)
          if (res.authSetting['scope.userInfo'] === true) {
            wx.getUserInfo({
              success: function (userData) {
                console.log(userData.userInfo)
                if (userData.userInfo) {
                  that.userInfo = userData.userInfo
                }
              }
            })
            let tokenTime = wx.getStorageSync('tokenTime')
			if (tokenTime == null || new Date().getTime() - tokenTime > 1000 * 60 * 60) {
			  that.login()
			}
          } else {
            console.log('用户还未授权过')
          }
        }
      })
    },
    login () {
      var that = this
      if (that.userInfo.nickName) {
        return
      }
      wx.login({
        success(res) {
          if (res.code) {
            that.$http.post(
              '/wx/login', res
            ).then(resData => {
              console.log(resData)
              var json = JSON.parse(resData.data)
              wx.setStorageSync('token', json.token)
              wx.setStorageSync('tokenTime', new Date().getTime())
            })
          }
        }
      })
    },
    getUserInfo (e) {
      var that = this
      console.log(e.mp.detail.userInfo)
      that.userInfo = e.mp.detail.userInfo
    }
  },

  created () {
    // let app = getApp()
  },

  mounted () {
    // 看用户是否授权过
    this.getUserData()
  }
}
</script>

<style scoped>
.userinfo {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.userinfo-avatar {
  width: 128rpx;
  height: 128rpx;
  margin: 20rpx;
  border-radius: 50%;
}

.userinfo-nickname {
  color: #aaa;
}

</style>

3)修改app.json,设置mine为首页

{
  "pages": [
    "pages/mine/main",
    "pages/index/main"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle": "black"
  },
  "tabBar": {
    "color": "#999",
    "backgroundColor": "#fafafa",
    "selectedColor": "#333",
    "borderStyle": "white",

    "list": [{
      "text": "首页",
      "pagePath": "pages/index/main",
      "iconPath": "static/tabs/home.png",
      "selectedIconPath": "static/tabs/home-active.png"
    }, {
      "text": "我的",
      "pagePath": "pages/mine/main",
      "iconPath": "static/tabs/orders.png",
      "selectedIconPath": "static/tabs/orders-active.png"
    }],

    "items": [{
      "name": "首页",
      "pagePath": "pages/index/main",
      "icon": "static/tabs/home.png",
      "activeIcon": "static/tabs/home-active.png"
    }, {
      "name": "我的",
      "pagePath": "pages/mine/main",
      "icon": "static/tabs/orders.png",
      "activeIcon": "static/tabs/orders-active.png"
    }],
    "position": "bottom"
  }
}

4)运行效果

  • 首次加载时:
    在这里插入图片描述
    在这里插入图片描述
  • 点击登录-授权页:
    在这里插入图片描述
  • 允许授权:
    在这里插入图片描述
    login接口返回数据,以及授权后获取的用户信息
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值