IM授权与访问控制
默认情况,GoEasy客户端可以向应用内的任何用户或群里发送消息,也可以订阅所有群的消息。
GoEasy访问控制
允许开发者对消息的发送和接收权限进行控制,比如:只允许特定人员与某个用户进行私聊, 或只允许特定用户参与某个群聊。
前置条件
- 已经掌握了IM消息发送和接收
- goeasy.js版本在2.2以上
1. 启用GoEasy IM访问限制
该功能目前尚在试运行阶段
启用IM的访问控制,请在线联系GoEasy工作人员后台启用
PubSub的访问控制为默认启用,可参照文档直接使用
启用后,私聊或群聊,都必须先携带access token。
2. 获得开发者服务器的授权
2.1 向开发者服务器发送授权请求
将客户端id
和私聊对象/群id
作为参数发送给开发者服务器,请求给予授权。
2.2 开发者服务器为IM生成access token
开发者服务器收到请求,应根据自己的业务逻辑来决定是否授予access token。
对于合法用户,请按照下列规则生成JWT格式的access token并返回客户端。 什么是JWT?
access token有效期内可重复使用,不需要为每条消息都生成一个
Header:
{
"alg": "HS256",//算法
"typ": "JWT" //类型
}
Payload
{
id: 'user-001', //必须与connect GoEasy时传入的id一致
to: ['group-001','group-002']/'user-002', //群id数组或私聊对象id
w: true, //写权限,是否允许发送
r: true, //写权限,是否允许订阅群消息
exp:1634109917// 过期时间, 表示token在此之前有效,为了安全,GoEasy不接受有效时间超过3小时的access token
}
Signature:
HMAC_SHA256(
secret, //应用的Secret key,登陆GoEasy->应用详情->Professional keys->Secret key
base64urlEncoding(header) + '.' +
base64urlEncoding(payload)
)
参考代码
- Java
- NodeJS
- PHP
- pom.xml里添加jjwt
<dependencies>
...
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
- 私聊
public String privateChatAccessToken(String id, String toId) {
//应用的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("to", toId)//接收方,私聊对象的id
.claim("w", true)//写权限,是否允许发送
.setExpiration(expirationTime)
.signWith(SignatureAlgorithm.HS256, secretKey.getBytes()).compact();
return accessToken;
}
- 群聊
public String groupChatAccessToken(String id, String... groupIds) {
//应用的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("to", groupIds)//需要授权的groupId列表, 支持一次为多个群授权
.claim("w", true)//写权限,是否允许发送
.claim("r", true)//读权限,是否允许订阅(接收)
.setExpiration(expirationTime)
.signWith(SignatureAlgorithm.HS256, secretKey.getBytes()).compact();
return accessToken;
}
- 安装jsonwebtoken
npm install jsonwebtoken
- 私聊
let jwt = require('jsonwebtoken');
let id = 'user-001'; //发送方,必须与connect GoEasy时传入的id一致
let toId = 'user-002'; //接收方,私聊对象的id
let payload = {
id: id,
to:toId,
w: true, //写权限,是否允许发送
};
let options = {
expiresIn: "3h" //token的有效时间,最长不能超过3小时,为了安全,GoEasy不接受有效时间大于3小时的accessToken
};
let secretKey = 'f7e4cf0f5c6db52d'; //应用的秘钥Secret key,登陆GoEasy->应用详情->Professional keys->Secret key
//签名,生成access token
let accessToken = jwt.sign(payload, secretKey, options);
- 群聊
let jwt = require('jsonwebtoken');
let id = 'user-001'; //发送方,必须与connect GoEasy时传入的id一致
let groupIds = ['group001']; //接收方,需要授权的groupId列表, 支持一次为多个群授权
let payload = {
id: id,
to: groupIds,
w: true, //写权限,是否允许发送
r: true, //写权限,是否允许订阅群消息
};
let options = {
expiresIn: "3h" //token的有效时间,最长不能超过3小时,为了安全,GoEasy不接受有效时间大于3小时的accessToken
};
let secretKey = 'f7e4cf0f5c6db52d'; //应用的秘钥Secret key,登陆GoEasy->应用详情->Professional keys->Secret key
//签名,生成access token
let accessToken = jwt.sign(payload, secretKey, options);
安装firebase/php-jwt
私聊
use Firebase\JWT\JWT;
function privateChatAccessToken($id, $toId){
$payload = array(
"id" => $id,//必须与connect GoEasy时传入的id一致
"to" => $toId,//私聊对象的id
"w" => true,//写权限,是否允许发送
"exp"=> strtotime('+3 hour')//token的有效时间,最长不能超过3小时,为了安全,GoEasy不接受有效时间大于3小时的access token
);
//应用的Secret key,登陆GoEasy->应用详情->Professional keys->Secret key
$secretKey = "f7e4cf0f5c6db52d";
$accessToken = JWT::encode($payload, $secretKey);
return $accessToken;
}
- 群聊
use Firebase\JWT\JWT;
function groupChatAccessToken($id, $groupIds){
$payload = array(
"id" => $id,//必须与connect GoEasy时传入的id一致
"to" => $groupIds,//需要授权的groupId列表, 支持一次为多个群授权
"w" => true,//写权限,是否允许发送
"r"=> true, //写权限,是否允许订阅群消息
"exp"=> strtotime('+3 hour')//token的有效时间,最长不能超过3小时,为了安全,GoEasy不接受有效时间大于3小时的access token
);
//应用的Secret key,登陆GoEasy->应用详情->Professional keys->Secret key
$secretKey = "f7e4cf0f5c6db52d";
$accessToken = JWT::encode($payload, $secretKey);
return $accessToken;
}
3. 发送群聊和私聊消息
若启用了IM访问限制,发送消息时,必须传入正确的access token
im.sendMessage({
message: textMessage,
accessToken: accessToken,
onSuccess: function () { //发送成功
console.log("Private message sent successfully.", textMessage);
},
onFailed: function (error) { //发送失败
console.log('Failed to send private message,code:' + error.code + ' ,error ' + error.content);
}
});
4. 订阅群消息
若启用了IM访问限制,订阅群消息时,必须传入正确的access token。
//订阅群消息
var groupIds = ["group001"];
im.subscribeGroup({
groupIds: groupIds,
accessToken: accessToken,
onSuccess: function () { //订阅成功
console.log("Group message subscribe successfully.");
},
onFailed: function (error) { //订阅失败
console.log("Failed to subscribe group message, code:" + error.code + " content:" + error.content);
}
});