小程序登录鉴权服务,客户端底层 SDK,登录鉴权、业务请求、鉴权重试模块 Typescript 实战。

系列

  1. 云原生 API 网关,gRPC-Gateway V2 初探
  2. Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第一篇
  3. Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第二篇
  4. Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务(三):RSA(RS512) 签名 JWT
  5. Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(四):自动生成 API TS 类型
  6. Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(五):鉴权 gRPC-Interceptor 拦截器实战

Demo: go-grpc-gateway-v2-microservice

前端底层初步搭建(SDK)

新建 client/miniprogram/service/sdk.ts 文件,来初步搭建一下我们前端的底层公共设施。

定义一个 SDK namespace

export namespace SDK {

}

定义相关常量 & Interface

const serverAddr = 'http://localhost:8080'
const AUTH_ERR= 'AUTH_ERR'
const authData = {
token: '',
expiryMs: 0
}
interface RequestOption<REQ, RES> {
method: 'GET'|'PUT'|'POST'|'DELETE'
path: string
data: REQ
respMarshaller: (r: object)=>RES
}
interface AuthOption {
attachAuthHeader: boolean
retryOnAuthError: boolean
}

这里主要根据当前需求,做了如下事情:

  • 抽出服务器地址 serverAddr
  • 定义一个授权失败 401 常量
  • token 相关暂时存到内存中
  • 定义客户端 wx.request 所必须的参数类型
  • 控制授权请求相关逻辑(是否附加 Auth Header & 重试等)

wx.login 改写成 Promise 形式

export function wxLogin(): Promise<WechatMiniprogram.LoginSuccessCallbackResult> {
return new Promise((resolve, reject) => {
wx.login({
success: resolve,
fail: reject,
})
})
}

请求公共逻辑 wx.request 编写

export function sendRequest<REQ, RES>(o: RequestOption<REQ, RES>, a: AuthOption): Promise<RES> {
const authOpt = a || {
attachAuthHeader: true,
}
return new Promise((resolve, reject) => {
const header: Record<string, any> = {}
if (authOpt.attachAuthHeader) {
if (authData.token && authData.expiryMs >= Date.now()) {
header.authorization = 'Bearer '+ authData.token
} else {
reject(AUTH_ERR)
return
}
}
wx.request({
url: serverAddr + o.path,
method: o.method,
data: o.data,
header,
success: res => {
if(res.statusCode === 401) {
reject(AUTH_ERR)
} else if (res.statusCode >= 400) {
reject(res)
} else {
resolve(
o.respMarshaller(
camelcaseKeys(res.data as object, { deep: true }),
)
)
}
},
fail: reject
})
})
}

登录模块(login)编写

export async function login() {
if (authData.token && authData.expiryMs >= Date.now()) {
return
}
const wxResp = await wxLogin()
const reqTimeMs = Date.now()
const resp = await sendRequest<auth.v1.ILoginRequest, auth.v1.ILoginResponse>({
method: "POST",
path: "/v1/auth/login",
data: {
code: wxResp.code,
},
respMarshaller: auth.v1.LoginResponse.fromObject
}, {
attachAuthHeader: false,
retryOnAuthError: false,
})
authData.token = resp.accessToken!
authData.expiryMs = reqTimeMs + resp.expiresIn! * 1000
}

业务请求自动重试模块编写

 export async function sendRequestWithAuthRetry<REQ, RES>(o: RequestOption<REQ, RES>, a?: AuthOption): Promise<RES> {
const authOpt = a || {
attachAuthHeader: true,
retryOnAuthError: true,
}
try {
await login()
return sendRequest(o, authOpt)
} catch(err) {
if(err === AUTH_ERR && authOpt.retryOnAuthError) {
authData.token = ''
authData.expiryMs = 0
return sendRequestWithAuthRetry(o, {
attachAuthHeader: authOpt.attachAuthHeader,
retryOnAuthError: false
})
} else {
throw err
}
}
}

Todo Service

客户端具体服务层,这里是 Todo 这个服务。

我们新建一个文件控制客户端相关逻辑:client/miniprogram/service/todo.ts

创建一个 Todo

export namespace TodoService {
export function CreateTodo(req: todo.v1.ICreateTodoRequest): Promise<todo.v1.ICreateTodoResponse>{
return SDK.sendRequestWithAuthRetry({
method: "POST",
path: "/v1/todo",
data: req,
respMarshaller: todo.v1.CreateTodoResponse.fromObject
})
}
}

低层弄好后,上层堆业务就爽很多了。

Refs

我是为少
微信:uuhells123
公众号:黑客下午茶
加我微信(互相学习交流),关注公众号(获取更多学习资料~)

Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(六):客户端基础库 TS 实战的更多相关文章

  1. Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(五):鉴权 gRPC-Interceptor 拦截器实战

    拦截器(gRPC-Interceptor)类似于 Gin 中间件(Middleware),让你在真正调用 RPC 服务前,进行身份认证.参数校验.限流等通用操作. 系列 云原生 API 网关,gRPC ...

  2. Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(四):客户端强类型约束,自动生成 API TS 类型定义

    系列 云原生 API 网关,gRPC-Gateway V2 初探 Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第一篇 Go + gRPC-Gateway(V2) ...

  3. Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第一篇(内附开发 demo)

    简介 小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系. 系列 云原生 API 网关,gRPC-Gateway V2 初探 业务流程 官方开发接入文档 ...

  4. 微信小程序登录鉴权流程图

  5. Flask与微信小程序登录(后端)

    开发微信小程序时,接入小程序的授权登录可以快速实现用户注册登录的步骤,是快速建立用户体系的重要一步.这篇文章将介绍 python + flask + 微信小程序实现用户快速注册登录方案(本文主要进行后 ...

  6. 微慕WordPress小程序增强版

    2017年1月9日,张小龙在2017微信公开课Pro上发布的微信小程序正式上线.在过去的2年多的时间里,微信小程序领头,各大互联网平台也不甘落后,陆续推出自己的小程序.2018年7月4日,百度智能小程 ...

  7. JeeWx捷微3.1小程序版本发布,支持微信公众号,微信企业号,支付窗——JAVA版开源微信管家

    支持小程序,JeeWx捷微3.1小程序版本发布^_^ JeeWx捷微V3.1——多触点小程序版本管理平台(支持微信公众号,微信企业号,支付窗)   JeeWx捷微V3.1.0版本紧跟微信小程序更新,在 ...

  8. JAVA版开源微信管家—JeeWx捷微3.1小程序版本发布,支持微信公众号,微信企业号,支付窗

    支持小程序,JeeWx捷微3.1小程序版本发布^_^ JeeWx捷微V3.1--多触点小程序版本管理平台(支持微信公众号,微信企业号,支付窗) JeeWx捷微V3.1.0版本紧跟微信小程序更新,在原有 ...

  9. 小程序server-3-搭建WebSocket 服务

    小程序server-3-搭建WebSocket 服务: 1.安装 Node 模块 使用 ws 模块来在服务器上支持 WebSocket 协议,下面使用 NPM 来安装: cd /var/www/wxp ...

随机推荐

  1. django学习-8.django模板继承(block和extends)

    1.前言 django模板继承的作用:模板可以用继承的方式来实现复用,减少冗余内容. 一般来说,一个网站里一般存在多个网页的头部和尾部内容都是一致的,我们就可以通过模板继承来实现复用. 父模板用于放置 ...

  2. django学习-4.url动态传值

    1.前言 我们在浏览器访问一个网页A是通过一个指定的url地址去访问的.但在浏览器用一个不存在的url地址去执行访问是打不开正确的网页的,只会打开一个浏览器自带的有错误提示的网页. 在django框架 ...

  3. 运用Spock编写高质量单元测试

    单元测试作为提升代码质量的有效方法,目前在国内各大互联网公司的开发团队中,尤其是业务团队中却鲜少被使用.这主要由于大家对于单元测试有一些认知错误,或者没有正确的打开方式.至今我们团队在小剧场.零代码运 ...

  4. 新手不能忽视的MFC编程之CString

    首发文章 | 公众号:lunvey 作为一个新手,刚接触C++没多久.赶鸭子上架完成项目,鉴于之前有几年编程基础,所以很快就接触到了界面开发,由于用的是VC++6.0,所以自然而然就将MFC作为图形界 ...

  5. SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列教程02---创建后端工程

    本节代码开源地址 代码地址 项目运行截图 搭建后端工程 0.导入sql 在数据库导入 /* Navicat Premium Data Transfer Source Server : localhos ...

  6. su: Authentication failure解决方法

    su命令不能切换root,提示su: Authentication failure,需要sudo passwd root一次之后,下次再su的时候只要输入密码就可以成功登录.

  7. MySQL连接中出现的问题

    异常: Establishing SSL connection without server's identityverification is not recommended. According ...

  8. Vue框架- 指令操作

    目录 一.Vue指令操作 1. 表单指令 2. 条件指令 3. 循环指令 4. 斗篷指令 5. 实例成员:delimiter分隔符(了解) 6. filter过滤器 7. computed计算属性 8 ...

  9. 后端程序员之路 24、Redis hiredis

    Redishttps://redis.io/ Redis快速入门 - Redis教程http://www.yiibai.com/redis/redis_quick_guide.html wget ht ...

  10. docker nacos 集群部署

    1.准备机器3台 192.168.101.14 192.168.101.15 192.168.101.16 2.初始化sql(如果我们要搭建集群的话,那么肯定是不能用内嵌的数据库,不然数据无法共享.集 ...