Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(六):客户端基础库 TS 实战
2021-04-21 12:32
661 查看
小程序登录鉴权服务,客户端底层 SDK,登录鉴权、业务请求、鉴权重试模块 Typescript 实战。
系列
- 云原生 API 网关,gRPC-Gateway V2 初探
- Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第一篇
- Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第二篇
- Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务(三):RSA(RS512) 签名 JWT
- Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(四):自动生成 API TS 类型
- 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 }), ) ) } 56c }, 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 = '' ad8 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
- grpc-ecosystem/go-grpc-middleware
- API Security : API key is dead..Long live Distributed Token by value
- Demo: go-grpc-gateway-v2-microservice
- gRPC-Gateway
- gRPC-Gateway Docs
我是为少 微信:uuhells123 公众号:黑客下午茶 加我微信(互相学习交流),关注公众号(获取更多学习资料~)
相关文章推荐
- Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第二篇(内附开发 demo)
- Linux入职基础-5.24_可执行程序arpwatch做成系统一个服务(应用实战8)
- 微信小程序(应用号)开发新闻客户端的实战课程
- java程序员菜鸟进阶(四)oracle基础详解(四)oracle开启和关闭服务程序——解决安装oracle占用大量内存
- [java高级篇]Java微服务架构Dubbo篇——款高性能JavaRPC框架(Java高级程序元架构师教程)
- 个人中心页跟小程序登录流程—小程序入门与实战(十三)
- Go实战--Gorilla web toolkit使用之gorilla/rpc(gorilla/rpc/json)
- Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务)
- 【CSDN开源夏令营】 基于Web的SSH客户端,实现跨平台的云服务管理(三)远程登录功能的实现
- php基础系列:从用户登录处理程序学习mysql扩展基本操作
- 微信小程序开发记账应用实战服务端之用户注册与登录基于ThinkPHP5描述
- 破解微信Authorize 授权登录服务服务端课客户端使用
- 使用SSH客户端远程登录Linux主机(可替代samba、ftp服务)
- Spring cloud微服务实战——基于OAUTH2.0统一认证授权的微服务基础架构
- java 开发实战经典 练习题 第12章 第7题 完成系统登录程序 从命令行输入用户名和密码
- 学习笔记(13):零基础掌握 Python 入门到实战-异常处理:如何提高程序的稳定性
- 学习笔记(01):2020最新微信小程序基础+实战精讲视频-实战:Hello World的创建
- 第一章 基础 (续 为一个ASMX服务实现一个WCF客户端) 完结
- \t\tWeb启动客户端服务软件并完成登录动作
- spring 服务网关Gateway 自定义filter 程序写法