SSO 配置说明
名词解释
单点登录(Single Sign On,SSO) 指用户通过一次性身份鉴别即可登录所有账号关联的系统。在配置了SSO以后,新用户进入你的网站,可以用他们已有的账号(国内的微信、飞书等,国外的 Google、Facebook等)直接注册登录。
SSO 的优势
提高用户体验:让用户一次性登录多个应用程序,减少了重复的登录过程,提高了用户的体验 增强安全性:控制对应用程序的访问权限。这种方式比传统的用户名和密码验证更加安全可靠 减轻管理负担:企业通常管理众多不同应用程序和系统,使用SSO可以大幅减轻管理员们的工作量
配置步骤
SSO配置大致分为以下几步:
- 在Zion中新建SSO配置,拿到回调地址
- 前往身份提供商注册应用,将回调地址填入
- 返回Zion中填写该应用的信息(clientId、clientSecret等)
- 在页面上配置相应的行为### 在 Zion 中新建SSO配置 打开编辑器左上角项目设置,找到“单点登录方式”,点击“添加”
能看到会自动生成 callback 地址(回调地址)。单点登录的过程是:
- 在我们的网站上点击登录,跳转至身份提供商授权页面(比如谷歌登录页面)
- 在授权页面输入身份信息(邮箱密码等),完成授权
- 跳转回我们的网站而这个callback地址,就是在授权成功以后,跳转回来的地址
前往身份提供商注册应用,以 Google 为例
- 注册成为谷歌开发者:https://console.cloud.google.com/,注册成之后,点击下方界面所示的左上角,而后点击新建项目
- 填写项目信息,可以是默认信息,填写好之后,点击创建
- 完成项目创建后,在该项目下,点击 API 和服务选项
- 点击 OAuth 权限请求页面,选中【外部】,点击创建
- 回到项目当中,创建「隐私协议」以及「服务条款」页面,同时修改隐私协议页面的网页路径为privacy,服务条款页面的页面路径为terms,并在页面中设计并补充隐私协议内容以及服务条款内容,并设置对应的按钮可以跳转到这两个页面(获取这两个页面的链接)
- 按照图示完成 OAuth 内容的设置
img | img |
---|---|
- 设置权限范围,点击【添加或移除范围】按钮,添加 /auth/userinfo.email 以及 /auth/userinfo.profile 来获取用户的基本信息
- 继续完成接下来的配置即可,直接点击保存并继续即可
- 创建凭据,创建 OAuth 客户端 ID
- 填写 OAuth 客户端 ID 信息,应用类型为 Web,名称自定义
- 已授权的 JavaScript 来源:您的项目发布成功后的链接
- 已获取授权的重定向 URL : 在项目中添加的 SSO 配置下的回调地址,点击地址即可复制
- 复制凭证中的 客户端ID和客户端密钥
- 在项目中,填写客户端ID以及客户端密钥、scope,其中 scope 为 email 以及 profile即可,其他配置不用更改,直接保存即可
- 配置完成后,保存,并打开开关
在页面上配置相应的行为
在页面上配置相应的行为了,跟SSO相关的有三个行为:
- 注册/登录:SSO授权后,如果在account表中存在该SSO的信息,则用这个账号登录;否则,注册一个新用户,并绑定该SSO
- 绑定已有账号:SSO授权后,和当前登录的account绑定。如果当前是未登录状态,或者有其他的account绑定了该SSO,则绑定失败
- 和当前账号解绑:将当前account和SSO解绑
以注册/登录为例,配置相应的SSO和页面。注意:由于在SSO授权成功后,会跳转页面。因此无法使用原来页面的数据和行为,因此SSO成功时里,无法配置大部分的行为,只能够配置在后台运行的自定义行为。
获取 SSO 用户信息
- 在数据模型默认的账户表中增加 email 字段,类型为文本,增加完成后更新后端
- 在行为流中添加如下代码块,添加完成后保存行为流并更新后端
获取SSO返回的用户信息并更新账户表中的username以及email
function updateAccount(variables) {
const gql = `mutation updateAccount(
$accountId: bigint
$email: String
$name: String
) {
update_account(
_set: { email: $email, username: $name }
where: { id: { _eq: $accountId } }
) {
returning {
id
username
}
}
}
`;
return context.runGql("updateAccount", gql, variables, {
role: "admin",
}).update_account;
}
function queryAccount(variables) {
const gql = `query queryAccount($accountId: bigint) {
account(where: { id: { _eq: $accountId } }, limit: 1) {
id
username
}
}
`;
return context.runGql("queryAccount", gql, variables, {
role: "admin",
}).account[0];
}
const accountId = context.getSsoAccountId();
const queryAccountResult = queryAccount({ accountId });
if (queryAccountResult.username === null) {
const userInfo = context.getSsoUserInfo();
const userInfoJson = JSON.parse(userInfo);
const name = userInfoJson.username;
const email = userInfoJson.email;
const updateAccountVariables = {
accountId,
email,
name,
};
const updateAccountResult = updateAccount(updateAccountVariables);
}
在 SSO 执行成功时,调用该行为流,执行获取并更新账户表信息的行为