微信小程序-携带Token无感知登录的网络请求方案

去年写了一个网络请求工具封装的文章
微信小程序~ 网络请求工具的封装
当时没有考虑登录需要服务器token验证

token 是什么?

token 顾名思义就是令牌,也就是一种身份标志。用于和服务器确定身份,它具有时效性,超过有效时间身份标志就会失效。

服务器为什么需要token验证呢?

服务器有的API接口是需要相应的权限才能访问,比如:用户的收藏接口,肯定需要用户登录之后才能查看收藏列表,而想首页的文章列表、商品列表这类共用的数据,可以不需要登录权限就能查看。

客户端和服务器连接是通过HTTP协议连接,而HTTP协议是无状态的,这种无状态意味着程序需要验证每一次请求,从而辨别客户端的身份。在这之前,程序可以通过CookieSession技术来辨别请求的。

关于SessionCookie可以参考:【Cookie和Session详解】

SessionCookie由于会保存用户的信息,因此是不太安全的,那么Token出现就是为了解决这个问题。
那么 token是怎么和服务器验证身份的呢?

token 实现身份验证原理

实现原理大致如下:

微信小程序-携带Token无感知登录的网络请求方案_第1张图片

小程序里面如何实现?

  1. 实现一个网络请求工具(可实现携带 token不携带 token 访问api
  2. 在 小程序的 app.js里面初次调用
  3. 再根据不同的api请求权限调用网络工具中的相关方法

【可查看后续博文,会介绍从服务器端到小程序端的实现】
下面只是部分代码的实现:需源码请联系

import {
  Base64
} from 'js-base64'

import {
  Token
} from '../models/token.js'


// console.log(Base64)

const tips = {
  1: '抱歉,出现了一个错误'
}
// # 解构
class HTTP {
  request({
    url,
    data = {},
    method = 'GET'
  }) {
    return new Promise((resolve, reject) => {
      this._request(url, resolve, reject, data, method)
    })
  }

  requestNoAuth({
    url,
    data = {},
    method = 'GET'
  }) {
    return new Promise((resolve, reject) => {
      this._requestNoAuth(url, resolve, reject, data, method)
    })
  }
  // 需要token的请求
  _request(url, resolve, reject, data = {}, method = 'GET', noRefetch = false) {
    wx.request({
      // url: api.baseUrl + url,
      url:  url,
      method: method,
      data: data,
      header: {
        'content-type': 'application/json',
        Authorization: this._encode()
      },
      success: (res) => {
        const code = res.statusCode.toString()
        if (code.startsWith('2')) {
          resolve(res.data)
        } else {
          if (code == '403') {
            if (!noRefetch) {
              this._refetch(
                url,
                resolve,
                reject,
                data,
                method
              )
            }
          } else {
            reject()
            const error_code = res.data.error_code
            this._show_error(error_code)
          }
        }
      },
      fail: (err) => {
        reject()
        this._show_error(1)
      }
    })

  }

  // 不需要token的请求
  _requestNoAuth(url, resolve, reject, data = {}, method = 'GET', noRefetch = false) {
    wx.request({
      url: url,
      method: method,
      data: data,
      success: (res) => {
        const code = res.statusCode.toString()
        if (code.startsWith('2')) {
          resolve(res.data)
        } else {
            reject()
            const error_code = res.data.error_code
            this._show_error(error_code)
        }
      },
      fail: (err) => {
        reject()
        this._show_error(1)
      }
    })

  }

  _show_error(error_code) {
    if (!error_code) {
      error_code = 1
    }
    const tip = tips[error_code]
    wx.showToast({
      title: tip ? tip : tips[1],
      icon: 'none',
      duration: 2000
    })
  }

  _refetch(...param) {
    var token = new Token();
    token.getTokenFromServer((token) => {
      this._request(...param, true);
    });
  }

  _encode() {
    const token = wx.getStorageSync('loginToken')
    const base64 = Base64.encode(token + ':')
    return 'Basic ' + base64
  }


}

export {
  HTTP
}

【未完,待续。】

你可能感兴趣的:(小程序之旅)