AICon 北京站 Keynote 亮点揭秘,想了解 Agent 智能体来就对了! 了解详情
写点什么

实现验证逻辑、发布 API

  • 2019-10-09
  • 本文字数:3822 字

    阅读完需:约 13 分钟

实现验证逻辑、发布 API

在上一篇中我们创建了 API,并实现了 Lambda 函数和 API 的集成。在这一篇中,我们将具体实现对接微信开放平台验证微信用户的业务逻辑。为了简化说明,我们只选取了登录验证的主线业务流程,其中服务端 API 的主要步骤包括:


1.调用微信开放平台接口,使用 code 参数换取微信平台的 access_token。


2.调用微信开放平台接口,使用微信平台的 access_token 获取微信用户的 UnionId。


3.根据微信用户的 UnionId,在 DynamoDB 表中查询出本系统中的用户 userId。


4.以本系统中的用户 userId 调用 Cognito 接口获取 OpenIdTokenForDeveloperIdentity。


5.返回结果给客户端。


实际生产环境的业务流程还要包含用户首次验证本系统时,在 DynamoDB 表中尚未保存和微信平台用户关联关系时,引导用户到本系统的验证,比如输入用户名和密码或手机号和短信验证码,验证通过后再保存到 DynamoDB 表中,再获取 OpenIdTokenForDeveloperIdentity 并返回结果。我们这里使用已注册用户的单纯登录验证流程,因此在开发调试过程中首次获得 UnionId 时先手工在 DynamoDB 表中插入一条记录,以便模拟用户关联关系已存在于 DynamoDB 表中的情况。

Lambda 函数增加实现微信登录验证逻辑

我们先创建一个 cn.amazonaws.lambda.cognitowechat.util 包,然后放一个常用的 HttpConnection 工具类。然后再创建一个 WxClient.java 类,用于调用微信平台的接口获取相关微信数据,这个类中需要解析 JSON 数据,所以在 pom.xml 中增加以下依赖包。


<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
复制代码


WxClient.java 类主要就是 2 个方法,用于获取微信平台的 access_token 以及微信用户的 UnionId。详情请见源码,及微信开放平台说明文档《授权后接口调用(UnionID)》。


我们在 CognitoWechat 里增加验证的主方法 authenticateUser(),并以这个方法来调试调用微信平台接口。


private CognitoUser authenticateUser(String code){
WechatUser user = new WechatUser();
WxClient wxClient = new WxClient();
LinkedHashMap<String, String> ret = wxClient.getWxToken(code);
String accessToken = (String) ret.get("access_token");
String openid = (String) ret.get("openid");
user = wxClient.getWxUser(accessToken, openid);
String unionid = user.getUnionid();
System.out.println(TAG+" unionid= "+unionid);
return null;
}
复制代码


这时,需要我们再打开 Android Studio,调试我们已经完成微信登录关联的 App,获取一个当前的微信登录的 code 参数,比如 code=061quGYt0DDI1i1tSoXt0s6yYt0quGYY,用于我们后续服务端函数的开发。


先把 handleRequest() 方法改成如下这样:


public CognitoWechatResponse handleRequest(Object input, Context context) {
context.getLogger().log("Input: " + input);
CognitoWechatResponse cwResponse = new CognitoWechatResponse();
@SuppressWarnings("unchecked")
LinkedHashMap<String, String> inputHashMap = (LinkedHashMap<String, String>)input;
String code = (String) inputHashMap.get("code");
WechatUser user = authenticateUser(code);
if(user!=null){
cwResponse.setUserId(user.getUserId());
cwResponse.setStatus("true");
}
return cwResponse;
}
复制代码


然后就可以用刚才获取的 code 参数,来运行 Lambda 函数,用于测试微信开放平台接口调用正常。还是在项目右键菜单找到 Amazon Web Services,再点选 Run Function to AWS Lambda…。在弹出的运行对话框中,JSON 输入格换成刚才获取的 code 参数值,然后执行之。



可以看到窗格中输出一系列调试信息,已经从微信开放平台获取了的微信用户信息。

Lambda 函数查询 DynamoDB 表

根据前述模拟已存在的用户情况,我们把刚才获取到的 UnionId 以及模拟的用户 ID 如 123 手工插入到 DynamoDB 表 WechatUser 中。然后继续在 Lambda 函数中增加查 WechatUser 表的逻辑。我们使用经典的 DynamoDBMapper 来做一次读表查询即可。


我们在 Java 工程中添加相应的 DynamoDB 数据表对象。


package cn.amazonaws.lambda.cognitowechat;


import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;


@DynamoDBTable(tableName = "WechatUser")
public class WechatUser {
private String unionid;
private Integer userId;


@DynamoDBHashKey(attributeName = "unionid")
public String getUnionid() {
return unionid;
}


public void setUnionid(String unionid) {
this.unionid = unionid;
}


@DynamoDBAttribute(attributeName = "userid")
public Integer getUserId() {
return userId;
}


public void setUserId(Integer userId) {
this.userId = userId;
}


public WechatUser() {
}
}
复制代码


在 authenticateUser()方法里添加以下代码段。


AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.standard()
.withRegion(REGION)
.build();
DynamoDBMapper mapper = new DynamoDBMapper(ddb);
user = mapper.load(WechatUser.class, unionid);
if(user!=null){
Integer userId = user.getUserId();
System.out.println(TAG+" userid= "+userId);
return user;
}
复制代码


测试一下,在 AWS 上执行 Lambda 函数,可以得到从 WechatUser 表读取出的 userid=123。

Lambda 函数获取 Cognito 的 OpenIdToken

在 CognitoWechat 类中增加 2 个常量,配置上 Cognito 身份池的参数,这 2 个参数可以到 Amazon Cognito 控制台我们前面创建的身份池 CognitoWechat 中查找。


private static final String IDENTITY_POOL_ID = "cn-north-1:12345678-90ab-cdef-1234-567890abcdef ";
private static final String developerProvider = "cn.aws.cognitowechat";
复制代码


添加一个新方法 getCognitoUser ,用于获取 Cognito 的 OpenIdToken。


private CognitoUser getCognitoUser(Integer userId){
AmazonCognitoIdentity client = AmazonCognitoIdentityClientBuilder.defaultClient();
GetOpenIdTokenForDeveloperIdentityRequest tokenRequest = new GetOpenIdTokenForDeveloperIdentityRequest();
tokenRequest.setIdentityPoolId(IDENTITY_POOL_ID);


HashMap<String, String> map = new HashMap<String, String>();
map.put(developerProvider, userId.toString());


tokenRequest.setLogins(map);
tokenRequest.setTokenDuration(new Long(10001));


GetOpenIdTokenForDeveloperIdentityResult result = client.getOpenIdTokenForDeveloperIdentity(tokenRequest);
CognitoUser cognitoUser = new CognitoUser();
cognitoUser.setUserId(userId);
cognitoUser.setOpenIdToken(result.getToken());
cognitoUser.setIdentityId(result.getIdentityId());
System.out.println(TAG+" identityId = "+result.getIdentityId()+"; getToken = "+result.getToken());
return cognitoUser;
}
复制代码


再测试一下,在 AWS 上执行 Lambda 函数,可以得到从 Cognito 获取到的 identityId 和 token 就可以了。


然后我们把 handleRequest()方法写完整,把 getCognitoUser()方法返回的结果输出成 Lambda 函数的响应结果。最后到 API Gateway 控制台,在 API 中测试,可以检验整个服务端接口已经调试成功。


小结

这一篇中我们实现了对接微信开放平台验证微信用户的业务逻辑,并调试通了 Lambda 函数和 API Gateway。在下一篇中,我们将最终完成 Android 客户端,实现授权并访问 AWS 资源。

索引

Amazon Cognito 集成微信登录部署系列(一)Cognito 身份池、Dynamodb 表和创建 Lambda 函数


Amazon Cognito 集成微信登录部署系列(二)用 Lambda 开发服务端 API


Amazon Cognito 集成微信登录部署系列(三)与 API Gateway 集成、处理输入参数、返回响应结果


Amazon Cognito 集成微信登录部署系列(四)实现验证逻辑、发布 API


Amazon Cognito 集成微信登录部署系列(五)客户端集成 Cognito 验证


作者介绍:


薛峰


亚马逊 AWS 解决方案架构师,AWS 的云计算方案架构的咨询和设计,同时致力于 AWS 云服务在国内和全球的应用和推广,在大规模并发应用架构、移动应用以及无服务器架构等方面有丰富的实践经验。在加入 AWS 之前曾长期从事互联网应用开发,先后在新浪、唯品会等公司担任架构师、技术总监等职位。对跨平台多终端的互联网应用架构和方案有深入的研究。


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/amazon-cognito-wechat-deployment-4/


2019-10-09 14:351480
用户头像

发布了 1905 篇内容, 共 145.6 次阅读, 收获喜欢 81 次。

关注

评论

发布
暂无评论
发现更多内容

对Stream-API的用法鼓吹够多了,但性能到底怎么样呢?,mybatis和spring集成原理

Java 程序员 后端

如何理解互斥锁、条件锁、读写锁以及自旋锁(1),mysql入门到精通电子书

Java 程序员 后端

如何让自己像打王者荣耀一样发了疯、拼了命、石乐志的学习

Java 程序员 后端

如果当时这16道题能答好,现在应该已经被录取了(记一次面试的亲身经历 2020-9-9

Java 程序员 后端

学习高并发的前置知识——Java中的线程基础,springcloud实战演练

Java 程序员 后端

华为云专家向宇:工欲善其事必先利其器,才能做数据的“管家”

华为云数据库小助手

GaussDB GaussDB(for Influx) 华为云数据库 华为云数据库创新Lab

学IT的人太多了,现在入行还有出路吗?,linux环境高级编程

Java 程序员 后端

学会RabbitMQ代理的连接,是一种怎样的体验?,mongodb教程

Java 程序员 后端

学弟学妹们请不要错过自己的“黄金奋斗三年”,java实战项目代码

Java 程序员 后端

学生管理系统(SSM简易版)总结,斗鱼Java开发二面被刷

Java 程序员 后端

安利一款非常NICE的-API-敏捷开发工具,java注释快捷键视频

Java 程序员 后端

完美!白嫖4份满分级“并发编程,java架构师技术栈

Java 程序员 后端

字节跳动,三面我败了!但是我把经验记录了下来,java编程思想第六版百度云

Java 程序员 后端

实现一个简单的“个人博客”项目,java基础大纲思维导图

Java 程序员 后端

小白都能看懂的简单爬虫入门案例剖析(爬虫入门看它就够了!

Java 程序员 后端

如何让阿三 Windows 10、11 的恢复分区(Recovery Partition

Java 程序员 后端

完全没想到,他竟然靠这个拿到了40万年薪的大厂AI岗offer!

Java 程序员 后端

完美!字节3-1级别大佬把《数据结构与算法(1),mybatisorm原理

Java 程序员 后端

实现一个简单的HTTP,京东java面试问题大全及答案大全

Java 程序员 后端

如何设计一个百万级用户的抽奖系统?,三面蚂蚁核心金融部

Java 程序员 后端

如何阅读一本书-读书笔记,java二到三年经验面试题

Java 程序员 后端

字节跳动Java开放岗面经:14天快速面试,已拿offer,Java全套百度云

Java 程序员 后端

Clickhouse技术分享

scalad

大数据 实时数仓 Clickhouse OLAP开源引擎

小白必看!结合实际实例,理解事务,多线程面试题java

Java 程序员 后端

少写点if-else吧,它的效率有多低你知道吗?,渣本二面阿里受挫

Java 程序员 后端

字节首席架构师整合面试痛点,成就399页Java框架核心宝典

Java 程序员 后端

学透这份java进阶笔记,才知道为什么能一起斩获几十家大厂offer一定是有原因的

Java 程序员 后端

完美!字节3-1级别大佬把《数据结构与算法,linux翻墙教程视频

Java 程序员 后端

如果当时这15道题能答好,现在应该已经被录取了(记一次面试的亲身经历 2020-7-20

Java 程序员 后端

字节跳动一年一更的400多页算法刷题宝典已更新,力扣官网沸腾

Java 程序员 后端

实习生想面阿里应该掌握掌握哪些知识点?给学弟学妹们支招

Java 程序员 后端

实现验证逻辑、发布 API_语言 & 开发_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章