跳到主要内容

PubSub(Websocket)授权与访问控制

前置条件

  • 已经掌握了pubsub客户端消息的发送和接收
  • goeasy.js版本2.2以上

1. 设置受保护的channel

使用PubSub在客户端发送或订阅消息时,channel前加上前缀‘protected-’, 表明这是一个受保护的channel,比如支付消息的channel定义为'protected-payment'。

对于protected channel,在订阅和发送消息时,必须要携带access token,否则无法进行。

2. 获得开发者服务器的授权

2.1 向开发者服务器发送授权请求

将客户端id(必须与连接GoEasy时传入的id一致)和channel作为参数发送给开发者服务器,请求给予授权。

2.2 开发者服务器为PubSub生成access token

开发者服务器收到请求,应根据自己的业务逻辑来决定是否授予access token。

对于合法用户,请按照下列规则生成JWT格式的access token并返回客户端。 什么是JWT?

access token有效期内可重复使用,不需要为每条消息都生成一个

Header:

    {
"alg": "HS256",//算法
"typ": "JWT" //类型
}

Payload

    {
id: 'user-001', //必须与connect GoEasy时传入的id一致
channel:'protected-payment', //授权的channel
w: true, //写权限,是否允许publish
r: false, //读权限,是否允许subscribe
exp:1634109917// 过期时间, 表示token在此之前有效,为了安全,GoEasy不接受有效时间超过3小时的access token
}

Signature:

    HMAC_SHA256(
secret, //应用的Secret key,登陆GoEasy->应用详情->Professional keys->Secret key
base64urlEncoding(header) + '.' +
base64urlEncoding(payload)
)

参考代码

  • pom.xml里添加jjwt
<dependencies>
...
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
public String pubSubAccessToken(String id, String protectedChannel) {

//应用的Secret key,登陆GoEasy->应用详情->Professional keys->Secret key
String secretKey = "f7e4cf0f5c6db52d";

//token的有效时间,最长不能超过3小时,为了安全,GoEasy不接受有效时间大于3小时的access token
Date expirationTime = new Date(new Date().getTime() + TimeUnit.HOURS.toMillis(3));

String accessToken = Jwts.builder()
.setHeaderParam("alg", "HS256")
.setHeaderParam("typ", "JWT")
.claim("id", id)//发送方,必须与connect GoEasy时传入的id一致
.claim("channel", protectedChannel)//接收方,授权的channel
.claim("w", true)//写权限,是否允许发送(publish)
.claim("r", true)//读权限,是否允许接收(subscriber)
.setExpiration(expirationTime)
.signWith(SignatureAlgorithm.HS256, secretKey.getBytes()).compact();

return accessToken;
}

3. 订阅消息

要订阅protected channel的消息,必须要传入正确的access token,否则无法订阅。


pubsub.subscribe({
channel: "protected-payment",
accessToken: accessToken, //对于protected channel,订阅时必须要传入正确的access token
onMessage: function (message) {
console.log("Channel:" + message.channel + " content:" + message.content);
},
onSuccess: function () {
console.log("Channel订阅成功。");
},
onFailed: function (error) {
console.log("Channel订阅失败, 错误编码:" + error.code + " 错误信息:" + error.content)
}
});

4. 发送消息

向protected channel,发送消息时必须要传入正确的access token,否则无法发送


pubsub.publish({
channel: "protected-payment",//替换为您自己的channel
accessToken: accessToken, //对于protected channel,发送时必须要传入正确的access token
message: "Hello GoEasy!",//替换为您想要发送的消息内容
onSuccess: function () {
console.log("消息发布成功。");
},
onFailed: function (error) {
console.log("消息发送失败,错误编码:" + error.code + " 错误信息:" + error.content);
}
});