Skip to content

身份验证 + 社交 (@colyseus/social)

弃用通知

@colyseus/social 模块即将被完全弃用. 目前我们建议使用 Firebase, Auth0 或其他身份证验服务.

在此介绍 @colyseus/social 的配置和用法.

@colyseus/social 是一个实验性模块, 提供通用型后端服务, 以方便多人游戏的开发. 欢迎为此 API 提供建议和改进方法.

Tip

如果想要实现自己的身份验证方法,请参考 Room » onAuth().

安装

  1. 下载和安装 MongoDB

  2. 安装 @colyseus/social 模块.

npm install @colyseus/social
npm install express-jwt

  1. 导入和公开 @colyseus/social 提供的 Express 入口
import express from "express";
import socialRoutes from "@colyseus/social/express"

const app = express();
app.use("/", socialRoutes);

app.listen(8080);
const express = require("express");
const socialRoutes = require("@colyseus/social/express").default;

const app = express();
app.use("/", socialRoutes);

app.listen(8080);

服务器端配置

环境变量

  • MONGO_URI: MongoDB 连接 URI
  • JWT_SECRET: 用于身份验证的安全保密字符串
  • FACEBOOK_APP_TOKEN: Facebook 应用令牌 ("appid|appsecret")

服务器端 API

@colyseus/social 里提供了 MongoDB 模块,以及令牌验证功能.

typescript import { User, FriendRequest, verifyToken } from "@colyseus/social";

实现 onAuth 以检索当前用户

import { User, verifyToken } from "@colyseus/social";

class MyRoom extends Room {

  async onAuth(client, options) {
    // 令牌身份验证
    const token = verifyToken(options.token);

    // 以用户 id 查找用户
    return await User.findById(token._id);
  }

  onJoin(client, options, user) {
    console.log(user.username, "has joined the room!");
  }

}

触发点

hooks.beforeAuthenticate

在用户登录或注册之前, 会触发 beforeAuthenticate.

import { hooks } from "@colyseus/social";

hooks.beforeAuthenticate((provider, $setOnInsert, $set) => {
    // 注册时赋予默认元数据
    $setOnInsert.metadata = {
      coins: 100,
      trophies: 0
    };
});

hooks.beforeUserUpdate

在用户 通过 save() 方法 更新自己的信息之前, 会触发 beforeUserUpdate.

import Filter from "bad-words";
const filter = new Filter();

hooks.beforeUserUpdate((_id, fields) => {
  if (fields['username'] && filter.isProfane(fields['username'])) {
    throw new Error("no_swearing_allowed");
  }
})

客户端 API

登录

匿名

await client.auth.login();
await client.Auth.Login();
client.auth:login(function(err, auth)
  -- ...
end);

电子邮件 + 密码

await client.auth.login({
  email: "user@example.com",
  password: "12345"
});
await client.Auth.Login("user@example.com", "12345");
client.auth:login({
  email = "user@example.com",
  password = "12345"
}, function(err, auth)
  -- ...
end)

Facebook

//
// 请提前安装和配置好 Facebook SDK
// - https://developers.facebook.com/docs/javascript/quickstart
// - https://developers.facebook.com/docs/facebook-login/web
//

FB.login(function(response) {
  if (response.authResponse) {
    client.auth.login({ accessToken: response.authResponse.accessToken });
  }
}, { scope: 'public_profile,email,user_friends' });
//
// 请提前安装和配置好 Facebook SDK
// - https://developers.facebook.com/docs/unity/gettingstarted
// - https://developers.facebook.com/docs/unity/examples#login
//
var perms = new List<string>(){"public_profile", "email", "user_friends"};
FB.LogInWithReadPermissions(perms, AuthCallback);

private void AuthCallback (ILoginResult result) {
    if (FB.IsLoggedIn) {
        client.Auth.Login(Facebook.Unity.AccessToken.CurrentAccessToken);
    }
}
client.auth:facebook_login(function(err, auth)
  pprint(auth)
end)

更新用户数据

您可以在客户端修改 username, displayName, avatarUrl, lang, locationtimezone,然后调用 save() 方法保存.

client.auth.username = "Hello world!"
await client.auth.save();
client.Auth.Username = "Hello world!";
await client.Auth.Save();
client.auth.username = "Hello world!"
client.auth:save()

登出

client.auth.logout();
client.Auth.Logout();
client.auth:logout();

获取好友数据

const friends = await client.auth.getFriends();
friends.forEach(friend => {
  console.log(friend.username);
});
var friends = await client.Auth.GetFriends();
for (var i=0; i<friends.Length; i++)
{
  Debug.Log(friends[i].Username);
}
client.auth:get_friends(function(err, friends)
  for i, friend in pairs(friends) do
    print(friend.username)
  end
end);

获取在线好友

const friends = await client.auth.getOnlineFriends();
friends.forEach(friend => {
  console.log(friend.username);
});
var friends = await client.Auth.GetOnlineFriends();
for (var i=0; i<friends.Length; i++)
{
  Debug.Log(friends[i].Username);
}
client.auth:get_online_friends(function(err, friends)
  for i, friend in pairs(friends) do
    print(friend.username)
  end
end);

获取加好友请求

const friends = await client.auth.getFriendRequests();
friends.forEach(friend => {
  console.log(friend.username);
});
var friends = await client.Auth.GetFriendRequests();
for (var i=0; i<friends.Length; i++)
{
  Debug.Log(friends[i].Username);
}
client.auth:get_friend_requests(function(err, friends)
  for i, friend in pairs(friends) do
    print(friend.username)
  end
end);

同意加好友请求

await client.auth.acceptFriendRequest(friendId);
await client.Auth.AcceptFriendRequest(friendId);
client.auth:accept_friend_request(friend_id)

拒绝加好友请求

await client.auth.declineFriendRequest(friendId);
await client.Auth.DeclineFriendRequest(friendId);
client.auth:decline_friend_request(friend_id)

发送加好友请求

await client.auth.sendFriendRequest(friendId);
await client.Auth.SendFriendRequest(friendId);
client.auth:send_friend_request(friend_id)

拉黑用户

await client.auth.blockUser(friendId);
await client.Auth.BlockUser(friendId);
client.auth:block_user(friend_id)

拉黑恢复

await client.auth.unblockUser(friendId);
await client.Auth.UnblockUser(friendId);
client.auth:unblock_user(friend_id)
Back to top