小程序中的授权登录,实际上是分为两部分:

  1. 授权获取用户信息;
  2. 小程序登录;

    一、授权获取用户信息

    小程序中提供了一个 wx.getUserProfile() 方法来弹出授权窗口,获取用户信息。
    1. Page({
    2. getUserProfile() {
    3. wx.getUserProfile({
    4. desc: '用于完善个人资料',
    5. success: (res) => {
    6. console.log(res.userInfo)
    7. },
    8. fail: (err) => {
    9. }
    10. })
    11. },
    12. })

    二、小程序登录

    小程序登录,实际上是需要从微信的服务器中获取到每一个用户的 openid。

    1、获取 code

    小程序中提供了 wx.login() 方法用来获取 code:
    1. Page({
    2. getCode() {
    3. wx.login({
    4. success: (res) => {
    5. console.log(res.code)
    6. }
    7. })
    8. }
    9. })

    2、获取 token

    需要将 code 发送给后端,用来获取 token:
    1. Page({
    2. getToken() {
    3. wx.request({
    4. url: 'http://47.98.128.191:3001/users/wxLogin',
    5. method: 'POST',
    6. data: {
    7. code,
    8. appId: 'wxded7871137340bad',
    9. appSecret: '5e86d485eac69fe0e237331a6d2892e1',
    10. userInfo: this.data.userInfo
    11. },
    12. success: ({ data }) => {
    13. console.log(data);
    14. }
    15. })
    16. }
    17. })
    请求参数说明:
  • code:是必须的;
  • appId 和 appSecret:实际开发中,不需要传递,这里练习时我们传递自己的 appId 和 appSecret;
  • userInfo:是当前项目的服务器中需要该数据

    3、保存 token

    token获取成功后,我们可以使用小程序中提供了“数据缓存”方法,将 token 保存到本地存储:
    1. Page({
    2. getToken() {
    3. wx.request({
    4. // ...
    5. success: ({ data }) => {
    6. if(data.code) {
    7. wx.setStorage({
    8. key: 'token',
    9. data: data.token
    10. })
    11. }
    12. }
    13. })
    14. }
    15. })

    三、渲染用户信息

    渲染用户信息要分为两种情况:
  1. 用户之前没有登录,在授权登录成功后渲染用户信息;
  2. 用户之前已经登录过,直接渲染用户信息;

    1、授权登录后渲染

    前面我们在授权获取用户信息,就已经将获取成功的用户信息保存到了页面的 data 中,所以可以直接通过 data 中的 userInfo 进行判断渲染。
    页面参考代码如下:
    1. <view class="userInfo">
    2. <block wx:if="{{userInfo}}">
    3. <image class="avatar" src="{{userInfo.avatarUrl}}"></image>
    4. <text>{{userInfo.nickName}}</text>
    5. </block>
    6. <block wx:else>
    7. <image class="avatar" src="/assets/default.jpeg"></image>
    8. <text bindtap="getUserProfile">未登录</text>
    9. </block>
    10. </view>
    同时,考虑到除了当前页面外,我们在其他页面也有可能要使用用户信息,我们还可以在获取到用户信息后,将其保存成全局变量。
    我们对之前的 getUserProfile 方法再稍作修改:
    1. Page({
    2. getUserProfile() {
    3. wx.getUserProfile({
    4. desc: '用于完善个人资料',
    5. success: (res) => {
    6. this.setData({
    7. userInfo: res.userInfo
    8. })
    9. // 全局保存用户信息
    10. getApp().globalData.userInfo = res.userInfo;
    11. this.getCode();
    12. },
    13. fail: (err) => {
    14. console.log(err);
    15. }
    16. })
    17. },
    18. })

    2、用户已经登录过

    如果用户之前已经授权登录过当前小程序,那么再次进入小程序时,不需要再重新登录,应该直接渲染用户信息。
    所以,我们会在 app.js 中判断本地是否有 token,如果有 token,就发送请求到后端获取数据库中之前保存的用户信息:
    1. App({
    2. onLaunch() {
    3. this.getUserInfo();
    4. },
    5. getUserInfo() {
    6. // 判断本地是否有 token
    7. const token = wx.getStorageSync('token');
    8. if (token) {
    9. wx.request({
    10. url: 'http://47.98.128.191:3001/users/getUserInfo',
    11. header: {
    12. Authorization: token
    13. },
    14. success: ({data}) => {
    15. if(data.code) {
    16. // 将用户信息保存到全局
    17. this.globalData.userInfo = data.userInfo;
    18. }
    19. }
    20. })
    21. }
    22. }
    23. })
    用户信息保存到全局后,当用户再进入其他需要渲染用户信息的页面,我们就可以在 onLoad 生命周期中获取全局数据,并保存到页面自己的 data 中。
    例如我们进入个人中心页面时:
    1. Page({
    2. onLoad(options) {
    3. this.setData({
    4. userInfo: getApp().globalData.userInfo
    5. })
    6. }
    7. })
    注意:要查看效果,需要将小程序回到“普通编译”模式中,用户刷新时先进入首页,再切换到其他页面。