快速开始
快速开始:认证你的第一个用户
概述
当使用 GenAuth 进行用户认证时,你不需要自己实现用户管理逻辑,所有的相关操作(如创建删除用户、配置登录流程、重置密码等)都可以通过 GenAuth 控制台托管登录页、API & SDK 完成。用户资料将被安全地存储在 GenAuth 云上的数据库中,你不需要额外保存一份用户资料,而是直接使用 GenAuth 中存储的用户信息实现你的业务需求。为此,需要先 将你的业务数据与 GenAuth 用户联表。
使用 GenAuth 接入用户认证流程,一共有以下几种方式:
- 使用 GenAuth 托管登录页。
- 使用 GenAuth 提供的内嵌登录组件,可以集成到你的 Web 和移动端项目中,你不需要自己实现登录表单 UI。
- 使用 API & SDK,GenAuth 提供 RESTFul 和 GraphQL 两种形式的 API 以及 10 余种语言或框架的 SDK,你可以基于此自定义 UI 和认证流程。
GenAuth 可以集成到标准 Web 应用、单页 Web 应用、客户端应用以及后端应用等各种场景中,你可以分别阅读不同场景的接入方式:
当用户成功登录之后,你还需要:
使用托管登录页完成认证
GenAuth 托管登录页是最简单、安全的集成方式。这是因为登录流程由 GenAuth 维护,并由 GenAuth 保证安全。对于应用集成,建议使用 GenAuth 托管的登录流程。你的业务系统将用户重定向到 GenAuth 登录页,在此用户进行身份验证,然后重定向回在控制台配置的应用登录回调 URL。此设计被认为是安全性最佳实践。在自定义配置方面,托管模式提供了登录注册表单自定义配置,可通过控制台配置和 CSS 进行界面自定义。
本文档将会介绍如何使用 GenAuth 托管登录页快速实现一个完整的用户认证流程。
第一步:创建一个用户池
用户池 是你用户系统隔离的最小单位,你可以把不同场景的用户划分在不同的用户池。每个用户池下都可以有用户和应用程序,不同用户池之间的权限、应用、组织是完全隔离的。
如果你还没有 GenAuth 开发者账号,你需要先在 控制台 注册一个 GenAuth 开发者账号。注册完成之后,会引导你创建自己的用户池。
如果你已经有账号,想再创建一个用户池,可以点击左侧导航栏最上方的下拉按钮:

选择用户池类型:

有关创建用户池详情,请参阅 新老用户如何创建用户池。
第二步:创建一个应用
在控制台 应用->自建应用 页,你可以查看自己的应用列表:

有关创建和配置自建应用详情,请参阅 自建应用综述 。
应用创建成功后,点击右侧的 体验登录 按钮体验登录该应用:

在弹出的新窗口中,你可以看到这个 GenAuth 托管在线登录页,该登录页集成了登录、注册、忘记密码、社交登录、MFA 等功能:

有关创建和配置应用详情,请参阅 自建应用综述。
第三步:创建一个用户
点击 立即注册,选择 密码注册,输入邮箱和密码,再次确认密码,勾选同意隐私和服务条款后,点击 注册 按钮。

注册成功之后,你可以在控制台的 用户列表 页(控制台 用户管理 菜单下)看到该用户。
第四步:体验登录
回到登录页面,输入刚刚创建账号的邮箱和密码,点击 登录,登录成功之后,你将跳转到一个回调指引页面(在这个页面你可以查看后续详细的指引流程以及最佳实践,建议完整阅读一遍),你可以看到在 URL 中包含了 code 查询参数,我们下一步会用此 code 换取 token。

第五步:使用 Code 换取 Token
在实际应用中,你需要 修改回调地址为实际业务地址,该地址需要为一个后端地址。

获取到 code 之后,你需要使用 code 换取用户信息,Node.js 示例代码如下:
const axios = require("axios");
const qs = require("querystring");
const code2tokenResponse = await axios.post(
// 修改为你的应用域名
"https://AUTHING_APP_HOST/oidc/token",
qs.stringify({
code,
client_id: "AUTHING_APP_ID",
client_secret: "AUTHING_APP_SECRET",
grant_type: "authorization_code",
redirect_uri: "AUTHING_APP_REDIRECTURI",
}),
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
}
);
const { id_token, access_token } = code2tokenResponse.data;返回的数据中有 id_token 和 access_token。简单来说,id_token 相当于用户的身份凭证;access_token 是允许访问资源的钥匙。有关 Access Token 和 ID Token 的区别,请参阅 Access Token vs Id Token。
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IldZU3ZYbVhFRnZCaXcyNW1DTi1rMDZKeDk3d08xNVNlZGIwNjFhcWZ2WFEifQ.eyJqdGkiOiJJWWpZMzR3Y1hfX0tOX2NlbVdleHEiLCJzdWIiOiI1ZWU5YzRmYjM3Mjg5MGE4MTUyOTE4NzMiLCJpYXQiOjE2MTQ0MjE4NjMsImV4cCI6MTYxNTYzMTQ2Mywic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCBwaG9uZSIsImlzcyI6Imh0dHBzOi8vc2FtcGxlLWFwcC5hdXRoaW5nLmNuL29pZGMiLCJhdWQiOiI2MDA1M2I3NDE2NDc4ZGUyZTg4ZmFiNDMifQ.XKy6WTE4naogVaz60-u4L3B4O3l_tYBFnOd80089L-6Hm1bCjOaCY14lV4BN11HgZ_JbikrhE4-_SgbaAVIEsK0NC5P22Naz6as_mDv2tAVgH7eVAKKAHIUQQnWGB890KMY0ptRQXOtSI5Ge06LH1Qq3jPvDR-TklwlY8Kg2S1-oxqDQoZuwZxc5b2BC84M3uLYd5mskkVyGdXOtTBtaGhmn2gxUJ_OhqEVAVpsC_QZRi70D3jup1seG_oADXz11ViVP4EtzYx4jy_3CJLkBBZXGoBY6zzrEI02GPT0CXkKzBDQGymcXKK2FEWpeMYmgkKFTT2ZoI_WcsHrLeNJu7Q",
"expires_in": 1209600,
"id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ZWU5YzRmYjM3Mjg5MGE4MTUyOTE4NzMiLCJiaXJ0aGRhdGUiOiIiLCJmYW1pbHlfbmFtZSI6IiIsImdlbmRlciI6Ik0iLCJnaXZlbl9uYW1lIjoiIiwibG9jYWxlIjoiemhfQ04iLCJtaWRkbGVfbmFtZSI6IiIsIm5hbWUiOiIiLCJuaWNrbmFtZSI6IuW7lumVv-axnyIsInBpY3R1cmUiOiJodHRwczovL3RoaXJkd3gucWxvZ28uY24vbW1vcGVuL3ZpXzMyL0diUUtQMElGdlZOOENmd2UyQ0FPbzFBcW1FWnF1RXVUamhSVEZTRVdIaWJHbkhLaWFjY3RpY3J3VE50OUc4U3hOUG5MUzEwcmJBdFFYRGVKZkJ6VEEwb0p3LzEzMiIsInByZWZlcnJlZF91c2VybmFtZSI6IiIsInByb2ZpbGUiOiIiLCJ1cGRhdGVkX2F0IjoiMjAyMS0wMi0yN1QxMDoyOTo0MC4zNzFaIiwid2Vic2l0ZSI6IiIsInpvbmVpbmZvIjoiIiwiZW1haWwiOm51bGwsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicGhvbmVfbnVtYmVyIjpudWxsLCJwaG9uZV9udW1iZXJfdmVyaWZpZWQiOmZhbHNlLCJub25jZSI6IjVEdVdSRFZGRkUiLCJhdF9oYXNoIjoiaEdsRmh1YnZhbkNGSGNXc3RtVEtfQSIsImF1ZCI6IjYwMDUzYjc0MTY0NzhkZTJlODhmYWI0MyIsImV4cCI6MTYxNTYzMTQ2MywiaWF0IjoxNjE0NDIxODYzLCJpc3MiOiJodHRwczovL3NhbXBsZS1hcHAuYXV0aGluZy5jbi9vaWRjIn0.32N4cdIf0p7fiGEM6sPS6PH1JPtIwF3Ee4PUaCt6eXU",
"scope": "openid profile email phone",
"token_type": "Bearer"
}将 id_token 解码 之后,得到的示例数据如下,各字段含义参见上述 id_token:
{
"sub": "5ee9c4fb372890a815291873", // subject 的缩写,为用户 ID
"birthdate": "",
"family_name": "",
"gender": "M",
"given_name": "",
"locale": "zh_CN",
"middle_name": "",
"name": "",
"nickname": "Nickname",
"picture": "https://thirdwx.qlogo.cn/mmopen/vi_32/GbQKP0IFvVN8Cfwe2CAOo1AqmEZquEuTjhRTFSEWHibGnHKiaccticrwTNt9G8SxNPnLS10rbAtQXDeJfBzTA0oJw/132",
"preferred_username": "",
"profile": "",
"updated_at": "2021-02-27T10:29:40.371Z",
"website": "",
"zoneinfo": "",
"email": null,
"email_verified": false,
"phone_number": null,
"phone_number_verified": false
}你可以使用上一步换到的 access_token 来获取用户的详细信息,示例代码如下:
const axios = require("axios");
const token2UserInfoResponse = await axios.get(
"https://sample-app.authing.cn/oidc/me?access_token=" + access_token
);
console.log(token2UserInfoResponse.data);之后你需要将 id_token 传递回给前端,前端应该保存 id_token,并在每次请求后端接口时携带。后端接口应当先验证前端传来的 id_token 合法性,再处理用户请求。有关验证 Token 合法性的详情,请参阅 如何验证用户身份凭证(token)。
INFO
无后端场景该如何处理?
前面提到的 Code 换 Token 需要在后端完成,如果你属于无后端场景,可以使用以下两种模式:
使用 OIDC implicit 模式
在控制台 应用->自建应用 找到你的应用,在 应用配置->其他配置->授权配置->授权模式 开启 implicit 模式,并勾选 id_token token 返回类型,然后让你的用户使用以下地址发起登录:
GET https://sample-app.authing.cn/oidc/auth?client_id=AUTHING_APP_ID&redirect_uri={回调地址}&scope=openid%20profile&response_type=id_token%20token&state={随机字符串}&nonce={随机字符串}GenAuth 以 URL hash 的形式直接返回 id_token 和 access_token 到回调地址(自建应用 应用配置 标签页 认证配置 模块),例如:
https://example.com/#id_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1Y2QwMjZlZjNlZDlmOTRkODBmZTM2YWUiLCJub25jZSI6IjE4MzEyODkiLCJzaWQiOiI4YzgzN2I5My01OTNlLTQzZjctYWMzNC0yYjRmZDU3ZGFhMTciLCJhdF9oYXNoIjoiVFFtbFlEVTVPZGF1Zjl0U0VKdHY5USIsInNfaGFzaCI6Ind3SDNXclV2b0hiSUp5TWVZVHU4bHciLCJhdWQiOiI1ZDAxZTM4OTk4NWY4MWM2YzFkZDMxZGUiLCJleHAiOjE1NjA0MDkzNjgsImlhdCI6MTU2MDQwNTc2OCwiaXNzIjoiaHR0cHM6Ly9vYXV0aC5hdXRoaW5nLmNuL29hdXRoL29pZGMifQ.T9M0s6rk4Teq6VOOBRIElgHK9KyM3q0ZJj2aS0VD_Fw&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3OE9XcVJNVXJEUXpMMXpHVzVtUWoiLCJzdWIiOiI1Y2QwMjZlZjNlZDlmOTRkODBmZTM2YWUiLCJpc3MiOiJodHRwczovL29hdXRoLmF1dGhpbmcuY24vb2F1dGgvb2lkYyIsImlhdCI6MTU2MDQwNTc2OCwiZXhwIjoxNTYwNDA5MzY4LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIiwiYXVkIjoiNWQwMWUzODk5ODVmODFjNmMxZGQzMWRlIn0.mR0MZDwlZWGRMsAZjQ27sDFFqYoDgZ6WHTK4C7JbML4&expires_in=3600&token_type=Bearer&state=jazz&session_state=26ec053be9f47d68dc430f84b97efb1095469fe10169a9e00ef4092718714b8b你可以从 url hash 中取出 id_token,然后可以通过解码 id_token 获取用户信息。详情请见 如何验证用户身份凭证(token)。
使用 GenAuth Web SDK
GenAuth 提供另外一种简单的前端获取用户信息的方式,无需处理回调或进行其他配置。
详细使用方式请查看 单点登录(SSO)。
访问个人中心
在 GenAuth 中创建的每个应用都有一个内置的给终端用户的个人中心页,地址为 {YOUR_APP_DOMAIN}/u,如「https://sample-app.authing.cn/u」,你可以通过浏览器直接访问该地址。

在此,终端用户可以查看和修改自己的个人信息、修改密码、绑定邮箱手机号、绑定 MFA 等。
使用登录组件
上述流程中,我们使用的是 GenAuth 运维的托管登录页面。同时我们还提供支持各种主流 Web 框架的 登录组件。相比在线的登录页,登录组件更加灵活,自定义能力更强。你可以将其集成到的自己的页面中,有关登录组件详情,请参阅 使用内嵌登录组件完成认证。
使用 API & SDK
至此你已经了解了如何借助 GenAuth 的托管登录页快速实现核心的登录注册流程。如果你想有更强的自定义需求,也可以使用 GenAuth 提供的 API & SDK ,详细流程请见 使用 API & SDK 完成认证。
使用内嵌登录组件完成认证
内嵌登录组件(Guard)被认为是灵活性和集成之间的最佳平衡。如果集成需要更深入的自定义级别,或者在一些前后端分离的场景中无法使用 托管模式,则建议使用此模式。内嵌登录组件由 GenAuth 构建和更新,使用行业最佳实践安全性设计,仅需要几行 JavaScript 代码就可以集成到你开发的项目中。它可以直接从 CDN 或 NPM 加载,也可以从源代码构建。GenAuth 登录组件同时提供 Javascript 原生、React、Vue 和 Angular 的多种集成模式,在你的任何项目中都可以无缝集成并享有高度自定义灵活性。更加详细的介绍请见 接入 GenAuth Guard。
INFO
你可以查看 托管登录页 vs 可嵌入登录组件 了解 GenAuth 托管的登录页和内嵌登录组件的区别。
内嵌登录组件介绍
GenAuth 内嵌登录组件集成了以下功能:
- 登录:包含账号密码登录(包括手机号 + 密码、邮箱 + 密码、用户名 + 密码)、验证码登录(短信验证码、邮箱验证码)以及移动端 APP 扫码。
- 注册:包含手机验证码注册和用户名密码注册。
- 社会化登录,如 GitHub 登录(需先在后台配置)。
- APP 扫码登录(需先接入 APP 扫码登录)。
- 小程序扫码登录(需先在后台配置)。
- 企业身份源登录(需要配置企业身份源)。
- 忘记密码以及重置密码。
- MFA 认证。
其具备以下特性:
- 轻量级:所有资源打包起来只有几百 kb;
- 响应式:兼容移动端和 PC 端网页;
- 定制化:可以支持完整的 UI 自定义功能。
不同前端框架的接入流程
无论使用哪一种框架,你都需要用到应用的 appId ,请先 前往控制台获取。关于 APP ID 所在位置,请参阅 应用配置。
ui-components-exampleCode snippet: ui-components-example
在后端验证用户的 Token 是否有效
用户信息的 token 字段为标准的 OIDC IdToken,你可以在后端使用应用的 ID 和 Secret 验证此 token。
示例的 token 如下:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ZjIxNTFiZWFlNWE4YjRjZTZiMGJhZTkiLCJiaXJ0aGRhdGUiOiIiLCJmYW1pbHlfbmFtZSI6IiIsImdlbmRlciI6IiIsImdpdmVuX25hbWUiOiIiLCJsb2NhbGUiOiIiLCJtaWRkbGVfbmFtZSI6IiIsIm5hbWUiOiIiLCJuaWNrbmFtZSI6IiIsInBpY3R1cmUiOiJodHRwczovL3VzZXJjb250ZW50cy5hdXRoaW5nLmNuL2F1dGhpbmctYXZhdGFyLnBuZyIsInByZWZlcnJlZF91c2VybmFtZSI6InRlc3RAZXhhbXBsZS5jb20iLCJwcm9maWxlIjoiIiwidXBkYXRlZF9hdCI6IjIwMjEtMDEtMThUMDc6NDg6NTUuNzgxWiIsIndlYnNpdGUiOiIiLCJ6b25laW5mbyI6IiIsImFkZHJlc3MiOnsiY291bnRyeSI6IiIsInBvc3RhbF9jb2RlIjoiIiwicmVnaW9uIjoiIiwiZm9ybWF0dGVkIjoiIn0sInBob25lX251bWJlciI6bnVsbCwicGhvbmVfbnVtYmVyX3ZlcmlmaWVkIjpmYWxzZSwiZW1haWwiOiJ0ZXN0QGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJkYXRhIjp7InR5cGUiOiJ1c2VyIiwidXNlclBvb2xJZCI6IjVhOWZhMjZjZjg2MzVhMDAwMTg1NTI4YyIsImFwcElkIjoiNjAwNTNiNzQxNjQ3OGRlMmU4OGZhYjQzIiwiaWQiOiI1ZjIxNTFiZWFlNWE4YjRjZTZiMGJhZTkiLCJ1c2VySWQiOiI1ZjIxNTFiZWFlNWE4YjRjZTZiMGJhZTkiLCJfaWQiOiI1ZjIxNTFiZWFlNWE4YjRjZTZiMGJhZTkiLCJwaG9uZSI6bnVsbCwiZW1haWwiOiJ0ZXN0QGV4YW1wbGUuY29tIiwidXNlcm5hbWUiOiJ0ZXN0QGV4YW1wbGUuY29tIiwidW5pb25pZCI6bnVsbCwib3BlbmlkIjpudWxsLCJjbGllbnRJZCI6IjVhOWZhMjZjZjg2MzVhMDAwMTg1NTI4YyJ9LCJ1c2VycG9vbF9pZCI6IjVhOWZhMjZjZjg2MzVhMDAwMTg1NTI4YyIsImF1ZCI6IjYwMDUzYjc0MTY0NzhkZTJlODhmYWI0MyIsImV4cCI6MTYxMjE2NTg4OCwiaWF0IjoxNjEwOTU2Mjg4LCJpc3MiOiJodHRwczovL3NhbXBsZS1hcHAuYXV0aGluZy5jbi9vaWRjIn0.SNyGBffF-zBqDQFINGxUJZrWSAADHQhbEOsKvnH4SLg你可以在 JWT.IO(国内用户可以访问此 镜像站)中解码此 ID Token :

其中 sub 字段为用户的 ID,aud 字段为应用的 ID,你可以通过 Microsoft identity platform ID tokens 了解 OIDC IdToken 每个字段的详细释义。
基本上所有语言都提供了检验 IdToken 的 Library,以 Node.js 为例,你可以使用 JSON Web Token 来验证 IdToken:
const jwt = require("jsonwebtoken");
try {
const data = jwt.verify("YOUR_ID_TOKEN", "YOUR_APP_SECRET");
} catch (error) {
// token might be invalid or expired
console.error(error);
}如果验证成功,你可以通过 sub 字段得到该用户的唯一 ID,之后你就可以将用户 ID 与自己的业务结合起来啦!如果你需要给不同的用户授权不同的角色、权限,你可以了解如何给用户授权角色、权限,以进行细粒度的权限控制。
详细的参数与事件列表
GenAuth 内嵌登录组件支持高度自定义化,除了自定义标题、Logo 等基础配置外,你还可以配置不同的登录方式,通过自定义 CSS 完全自定义样式等;除了成功登录事件外,GenAuth 内嵌登录组件还封装了成功注册、登录失败、登录注册方式切换等事件,详细文档请见 登录组件(Guard)文档。
使用 API & SDK 完成认证
在前面的指引中你已经了解了如何使用 GenAuth 托管的登录页和内嵌登录组件实现登录注册流程,不仅如此,我们还提供 RESTful、 GraphQL 两种形式的 HTTP API,以及十余种不同语言和框架的 SDK。你可以基于这些 API & SDK 资源,灵活地组合你需要的认证流程。
选择熟悉的 SDK
GenAuth 同时支持了 Java、JavaScript/Node.js、Python、PHP、C#、Swift、Go、Ruby、微信小程序等多种语言的 SDK,你可以选择自己熟悉的 SDK:
初始化 SDK
init-sdkCode snippet: init-sdk
使用 SDK 认证用户
以手机号验证码登录(如果用户账号不存在的话,会先创建一个账号)为例:
首先发送短信验证码
send-sms-codeCode snippet: send-sms-code
然后使用手机号验证码登录:
login-by-phone-codeCode snippet: login-by-phone-code
成功登录之后,你可以获取到该用户的用户信息,其中 token 为该用户的身份凭证,后续访问你后端资源的时候应该带上,然后在后端验证此 token 的身份。
验证用户 Token
用户信息的 token 字段为标准的 OIDC IdToken,你可以在后端使用应用的 ID 和 Secret 验证此 token。
示例的 token 如下:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ZjIxNTFiZWFlNWE4YjRjZTZiMGJhZTkiLCJiaXJ0aGRhdGUiOiIiLCJmYW1pbHlfbmFtZSI6IiIsImdlbmRlciI6IiIsImdpdmVuX25hbWUiOiIiLCJsb2NhbGUiOiIiLCJtaWRkbGVfbmFtZSI6IiIsIm5hbWUiOiIiLCJuaWNrbmFtZSI6IiIsInBpY3R1cmUiOiJodHRwczovL3VzZXJjb250ZW50cy5hdXRoaW5nLmNuL2F1dGhpbmctYXZhdGFyLnBuZyIsInByZWZlcnJlZF91c2VybmFtZSI6InRlc3RAZXhhbXBsZS5jb20iLCJwcm9maWxlIjoiIiwidXBkYXRlZF9hdCI6IjIwMjEtMDEtMThUMDc6NDg6NTUuNzgxWiIsIndlYnNpdGUiOiIiLCJ6b25laW5mbyI6IiIsImFkZHJlc3MiOnsiY291bnRyeSI6IiIsInBvc3RhbF9jb2RlIjoiIiwicmVnaW9uIjoiIiwiZm9ybWF0dGVkIjoiIn0sInBob25lX251bWJlciI6bnVsbCwicGhvbmVfbnVtYmVyX3ZlcmlmaWVkIjpmYWxzZSwiZW1haWwiOiJ0ZXN0QGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJkYXRhIjp7InR5cGUiOiJ1c2VyIiwidXNlclBvb2xJZCI6IjVhOWZhMjZjZjg2MzVhMDAwMTg1NTI4YyIsImFwcElkIjoiNjAwNTNiNzQxNjQ3OGRlMmU4OGZhYjQzIiwiaWQiOiI1ZjIxNTFiZWFlNWE4YjRjZTZiMGJhZTkiLCJ1c2VySWQiOiI1ZjIxNTFiZWFlNWE4YjRjZTZiMGJhZTkiLCJfaWQiOiI1ZjIxNTFiZWFlNWE4YjRjZTZiMGJhZTkiLCJwaG9uZSI6bnVsbCwiZW1haWwiOiJ0ZXN0QGV4YW1wbGUuY29tIiwidXNlcm5hbWUiOiJ0ZXN0QGV4YW1wbGUuY29tIiwidW5pb25pZCI6bnVsbCwib3BlbmlkIjpudWxsLCJjbGllbnRJZCI6IjVhOWZhMjZjZjg2MzVhMDAwMTg1NTI4YyJ9LCJ1c2VycG9vbF9pZCI6IjVhOWZhMjZjZjg2MzVhMDAwMTg1NTI4YyIsImF1ZCI6IjYwMDUzYjc0MTY0NzhkZTJlODhmYWI0MyIsImV4cCI6MTYxMjE2NTg4OCwiaWF0IjoxNjEwOTU2Mjg4LCJpc3MiOiJodHRwczovL3NhbXBsZS1hcHAuYXV0aGluZy5jbi9vaWRjIn0.SNyGBffF-zBqDQFINGxUJZrWSAADHQhbEOsKvnH4SLg你可以在该网站(国内用户可以访问此镜像站)中解码此 IdToken :

基本上所有语言都提供了检验 IdToken 的 Library,你可以选择自己熟悉的语言:
verify-id-tokenCode snippet: verify-id-token
如果验证成功,你可以获取到该 id_token 的用户信息,其中 sub 字段为用户的 ID,aud 字段为应用的 ID,你可以点此了解 IdToken 每个字段的详细释义。
接下来
识别用户身份之后,你可能还需要对该用户进行权限管理,以判断用户是否对此 API 具备操作权限。
验证用户身份凭证(token)
当你的用户成功登录后,GenAuth 会为该用户签发一个 OIDC IdToken 作为身份凭证。验证方式请查看验证 Token 文档。
一个示例解码过后的示例 OIDC IdToken 如下:
{
sub: '5f719946524ee1099229496b', // subject 的缩写,为用户 ID
birthdate: null,
family_name: null,
gender: 'U',
given_name: null,
locale: null,
middle_name: null,
name: null,
nickname: null,
picture: 'https://files.authing.co/user-contents/photos/9a9dc4d7-e756-45b1-81d8-095a28e476c6.jpg',
preferred_username: 'test1',
profile: null,
updated_at: '2020-09-30T07:12:19.401Z',
website: null,
zoneinfo: null,
email: 'test1@123.com',
email_verified: false,
phone_number: null,
phone_number_verified: false,
nonce: 'E65b1QoUYt',
at_hash: 'B3IgOYDDa0Pz8v1_9qZrAw',
aud: '5f17a529f64fb009b794a2ff',
exp: 1601453558,
iat: 1601449959,
iss: 'https://oidc1.authing.cn/oidc'
}其中 sub 为该 Id Token 的唯一标识,一般为用户 ID。
对用户进行权限管理
当你已经构建起用户系统,在某个时刻你的 API 就需要判断当前访问的用户是否能够访问当前资源了。这时候你就需要构建自己的权限系统。权限系统中一个很重要的概念是授权,授权指的是判断用户具备哪些权限的过程,与认证是两个完全不同的含义(有关认证与授权的概念和关联,请参阅 认证与授权)。
目前被大家广泛采用的两种权限模型为:基于角色的访问控制(RBAC)和基于属性的访问控制(ABAC),二者各有优劣:RBAC 模型构建起来更加简单,缺点在于无法做到对资源细粒度地授权(都是授权某一类资源而不是授权某一个具体的资源);ABAC 模型构建相对比较复杂,学习成本比较高,优点在于细粒度和根据上下文动态执行。
在 GenAuth 的权限系统中,我们通过用户、角色这两种对象实现了 RBAC 模型的角色权限继承,在此之上,我们还能围绕属性进行动态地、细粒度地授权,从而实现了 ABAC 权限模型。同时,我们为了满足大型系统中复杂组织架构的设计需求,将资源、角色、权限授权统一组合到一个权限分组中:

你可以基于 GenAuth 强大而又灵活的权限系统快速构建出适合你业务场景的权限模型。下面我们以现实中一个简单的场景为例。
权限模型介绍
什么是基于角色的访问控制(RBAC)
基于角色的访问控制(Role-based access control,简称 RBAC),指的是通过用户的角色(Role)授权其相关权限,简单来说,这相比直接授予用户权限,要更加灵活、高效、可扩展。

当使用 RBAC 时,通过分析系统用户的实际情况,基于共同的职责和需求,授予他们不同角色。你可以授予给用户一个或多个角色,每个角色具有一个或多个权限,这种 用户-角色、角色-权限 间的关系,让我们可以不用再单独管理单个用户,用户从授予的角色里面继承所需的权限。
以一个简单的场景(Gitlab 的权限系统)为例,用户系统中有 Admin、Maintainer、Operator 三种角色,这三种角色分别具备不同的权限,比如只有 Admin 具备创建代码仓库、删除代码仓库的权限,其他的角色都不具备。

我们授予某个用户「Admin」这个角色,他就具备了「创建代码仓库」和「删除代码仓库」这两个权限。
不直接给用户授权策略,是为了之后的扩展性考虑。比如存在多个用户拥有相同的权限,在分配的时候就要分别为这几个用户指定相同的权限,修改时也要为这几个用户的权限进行一一修改。有了角色后,我们只需要为该角色制定好权限后,给不同的用户分配不同的角色,后续只需要修改角色的权限,就能自动修改角色内所有用户的权限。
什么是基于属性的访问控制(ABAC)
基于属性的访问控制(Attribute-Based Access Control,简称 ABAC)是一种灵活的授权模型,通过一个或一组属性来控制是否有对操作对象的权限。 ABAC 属性通常来说分为四类:用户属性(如用户年龄),环境属性(如当前时间),操作属性(如读取)和对象属性(如一篇文章,又称资源属性),所以理论上能够实现非常灵活的权限控制: 
在 ABAC 权限模型下,你可以轻松地实现以下权限控制逻辑:
- 授权编辑 A 具体某本书的编辑权限;
- 当一个文档的所属部门跟用户的部门相同时,用户可以访问这个文档;
- 当用户是一个文档的拥有者并且文档的状态是草稿,用户可以编辑这个文档;
- 早上九点前禁止 A 部门的人访问 B 系统;
- 在除了上海以外的地方禁止以管理员身份访问 A 系统;
上述的逻辑中有几个共同点:
- 具体到某一个而不是某一类资源;
- 具体到某一个操作;
- 能通过请求的上下文(如时间、地理位置、资源 Tag)动态执行策略;
如果浓缩到一句话,你可以细粒度地授权在何种情况下对某个资源具备某个特定的权限。
授权模式介绍
GenAuth 支持两种授权模式:
- 通过基于 OAuth 2.0 流程中的授权码模式。
- 通过权限 API 对用户进行授权管理。
借助 GenAuth 实现权限模型
下面我们以调用权限 API 的模式为例。
创建角色
你可以使用 GenAuth 控制台创建角色:在权限管理 - 角色管理中,点击添加角色按钮:
- 角色 code: 该角色的唯一标志符,只允许包含英文字母、数字、下划线 _、横线 -,这里我们填 admin。
- 角色描述:该角色的描述信息,这里我们填管理员。
创建好三个角色:

你也可以使用 API & SDK 创建角色,详情请见角色 Management SDK。
授权用户角色
在角色详情页面,你可以将此角色授权给用户。你可以通过用户名、手机号、邮箱、昵称搜索用户:

选择用户之后点击确认,你可以查看被授权此角色的用户列表。
你也可以使用 API & SDK 给用户授予角色,详情请见角色 Management SDK。
在后端通过用户角色控制权限
当用户成功认证、获取到 Token 之后,你可以解析到当前用户的 ID,接下来你可以使用我们提供的 API & SDK 在后端获取该用户被授予的角色,这里以 Node.js 为例:
首先获取用户的被授予的所有角色列表:
import { ManagementClient } from 'authing-js-sdk'
const managementClient = new ManagementClient({
userPoolId: 'YOUR_USERPOOL_ID',
secret: 'YOUR_USERPOOL_SECRET',
})
const { totalCount, list } = await managementClient.users.listRoles('USER_ID')得到用户的所有角色之后,我们可以判断该用户是否具备 devops 这个角色:
if (!list.map((role) => role.code).includes('devops')) {
throw new Error('无权限操作!')
}创建资源
上一步我们通过用户是否具备某个角色来控制权限,这种权限控制还是比较粗粒度的,因为只判断了用户是否具备某个角色,而没有判断其是否具备某个特定的权限。GenAuth 在基于角色的访问控制模型(RBAC)的基础上,还能够围绕资源进行更细粒度的授权。
你可以把系统的一些对象抽象为资源,在这些资源上可以定义了一些操作。比如在本文的场景中,Repository、Tag、PR、Release Notes 都是资源,且这些资源都有对应的操作:
- Repository:创建、删除等。
- PR:开启、评论、合并等。
- Tag:创建、删除等。
- Release Notes:创建、阅读、编辑、删除等。
我们在 GenAuth 中创建这些资源:

授权角色操作资源的权限
而且 GenAuth 还同时支持给用户、角色授权,如果用户在某个角色中,他也将继承这个角色被授权的权限。所以 GenAuth 既能够实现标准的 RBAC 权限模型,也能在这基础上进行更细粒度、更动态的权限控制。 比如下面这个例子中,我们给 admin 这个角色授权了 repository 资源的 Create 和 Delete 权限:

在后端判断用户是否具备权限
在上一步我们通过资源授权,做到了授权给某个用户(角色)对某个特定资源的特定操作权限,我们在后端进行接口鉴权的时候,就可以做更细粒度的判断了:
首先初始化 Management SDK:
这里已 Node SDK 为例,我们同时还支持 Python、Java、C#、PHP 等语言的 SDK,详情请点击此。
import { ManagementClient } from 'authing-js-sdk'
const managementClient = new ManagementClient({
userPoolId: 'YOUR_USERPOOL_ID',
secret: 'YOUR_USERPOOL_SECRET',
})调用 managementClient.acl.isAllowed 方法,参数分别为:
- userId: 用户 ID,用户可以被直接授权特定资源的操作,也可以继承角色被授权的权限。
- resource: 资源标志符,如
repository:123表示 ID 为 123 的代码仓库,repository:\*表示代码仓库这一类资源。 - action: 特定操作,如
repository:Delete表示删除代码仓库这个操作。 - options: 其他选项,可选
- options.namespace,资源所属权限分组 code
const { totalCount, list } = await managementClient.acl.isAllowed(
'USER_ID',
'repository:123',
'repository:Delete'
)GenAuth 策略引擎会根据你配置的权限策略,动态执行策略,最后返回 true 或者 false,你只需要根据返回值就能判断用户是否具备操作权限。
总结
本文从最简单的 RBAC 权限模型开始,再在此之上实现了如何进行更细粒度、动态的 ABAC 权限模型,且整个过程是渐进地,你可以随着业务的复杂性不断变大,逐步地迁移到 ABAC 权限模型。
退出登录
GenAuth 支持多种退出方式:
- 从个人中心退出:此方式适合你使用 GenAuth 托管的在线个人中心的场景;
- 从前端退出:此方式适合几乎任何场景;
- 从后端登出:此方式适合管理员调用 API 强制下线用户的场景;
- 强制用户下线:此方式适合管理员使用控制台强制下线用户的场景。
从个人中心退出
终端用户可以访问 https://应用域名.authing.cn/u 进入个人中心,点击右上角的头像,点击退出。

从前端退出
引导你的终端用户访问 https://应用域名.authing.cn/login/profile/logout?redirect_uri={{CALLBACK_URL}} 进行退出,redirect_uri 可以填写一个退出后的回调地址,例如可以跳转到你的业务首页。
注意 ⚠️:你需要使用
encodeURIComponent对回调链接进行 URL Encode。
从后端登出
如果你需要在后端退出一个 GenAuth 用户,需要访问以下接口:
- 接口说明:用户池管理员在后端将 GenAuth 用户退出登录。
- 接口地址:
POSThttps://<你的应用域名>.authing.cn/api/v2/applications/:appId/kick-active-users - 请求头:
| 参数 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
| x-authing-userpool-id | string | 是 | 用户池 ID。 |
| Authorization | string | 是 | 用户池管理员 token |
- 请求参数:
| 参数 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
| userIds | string[] | 是 | 用户 ID 数组。 |
| appId | string | 是 | 应用 ID。 |
- 返回数据:
{
"code": 200,
"message": "强制下线成功"
}强制用户下线
用户池管理员可以通过控制台 > 应用 > 登录态管理,强制让用户下线。

接下来你可能需要
看到这里你已经对如何使用 GenAuth 有了一个基本的了解了,接下来你可以:
- 了解如何为你的应用添加社会化登录。
- 在应用之间实现单点登录。
- 对用户进行权限管理。
- 了解如何管理用户目录。
- 如果你有原有用户系统中的用户需要导入到 GenAuth,请务必阅读此部分的指引。
在标准 Web 应用中集成 GenAuth
本文以 Node.js Web 框架 Express 为例,介绍如何在传统的 Web 项目(如 Express MVC 、Django、PHP Laravel 等)中快速接入 GenAuth,实现登录、退出、获取用户信息等功能。
这里一共牵涉到三方:终端用户浏览器、应用服务器、 GenAuth 服务器,完整流程如下:
- 终端用户浏览器请求应用服务,发现用户未登录,跳转到 GenAuth 托管的登录页。
- 用户在此登录页完成登录之后,终端用户浏览器会在请求参数中携带授权码 (Authorization Code) 等数据跳转到应用服务器预先配置好的回调链。
- 应用服务器使用授权码 (Authorization Code) 向 GenAuth 服务器请求换取用户信息。
- 应用服务器获取到用户信息之后,建立与终端用户的会话。
- 终端用户得到登录成功提示,认证流程完成。
流程图如下所示:

在 GenAuth 中进行配置
在开始前,你需要在 GenAuth 中 创建一个应用。你可以前往 GenAuth 控制台的应用列表页面创建应用。
配置回调链接
路径:应用->自建应用->应用详情页->应用配置->认证配置
当用户在 GenAuth 登录成功之后,浏览器会跳转到你配置的回调链接(Callback URL)。此回调链接应该是你应用中的一个路由,你需要在此路由中完成换取用户信息等操作。你必须配置此回调链接,否则用户将无法登录,而会显示 invalid_redirect_uri 错误提示。
此示例代码的回调链接为 https://console.authing.cn/console/get-started,将其复制到 登录回调 URL 配置项中,然后点击 保存。更多信息,请参阅 应用配置

配置登出回调链接
你需要配置退出登录之后的回调地址(Logout URLs)。用户在 GenAuth 托管登录页退出登录之后,返回该地址。你必须配置此回调链接,否则用户将无法退出,而会显示 misconfiguration 错误提示。 此示例代码的回调链接为 http://localhost:3000,将其复制到 登出回调 URL 配置项中,然后点击保存。
集成 GenAuth 到你的系统
安装依赖
此处是 node.js 示例,你需要安装支持标准 OIDC 协议的 openid-client 和 passportjs 。
yarn add express express-session passport openid-clientJava 开发者可以使用 Spring 框架的 spring-security,详细接入流程请见文档。
初始化
在项目的最开始我们需要初始化 openid-client 的 Issuer,初始化参数如下:
- client_id: OIDC Client ID,在 GenAuth 中即你的 应用 ID;
- client_secret: OIDC Client Secret,在 GenAuth 中即你 应用的密钥;
- issuer: OIDC Issuer,你可以在应用的端点信息中获取。
获取方式如图所示,你需要保存好这些内容或记住获取方式,以后可能会频繁使用:

这里出于演示考虑,passport.serializeUser 中直接传 user 给回调函数 done,这会将用户信息存储在 req.session.passport.user 中,正式生产环境下不建议这么做,因为如果用户信息被修改而 session 没有更新,会造成数据不一致。passport.deserializeUser 传给回调函数 done 的第二个参数将会挂载到 req.user 上。如果你对 passport.js 还不够了解,建议先阅读 passport.js 官方文档。
passport.serializeUser(function(user, done) {
console.log("serializeUser", user);
done(null, user.sub);
});
passport.deserializeUser(function(userId, done) {
console.log("deserializeUser", userId);
done(null, userId);
});详细示例代码如下:
const express = require("express");
const session = require("express-session");
const passport = require("passport");
const { Strategy, Issuer } = require("openid-client");
const OIDC_CLIENT_ID = "YOUR_APPLICATION_ID";
const OIDC_CLIENT_SECRET = "YOUR_APPLICATION_SECRET";
const OIDC_ISSUER = "YOUR_OIDC_ISSUER";
const REDIRECT_URI = "http://localhost:3000/auth/callback";
(async () => {
const issuer = await Issuer.discover(OIDC_ISSUER);
const client = new issuer.Client({
client_id: OIDC_CLIENT_ID,
client_secret: OIDC_CLIENT_SECRET,
id_token_signed_response_alg: "HS256",
token_endpoint_auth_method: "client_secret_post",
});
passport.use(
"oidc",
new Strategy(
{
client,
params: {
redirect_uri: REDIRECT_URI,
scope: "openid profile email phone",
grant_type: "authorization_code",
response_type: "code",
},
},
(tokenset, userinfo, done) => {
return done(null, userinfo);
}
)
);
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
const app = express();
app.use(
session({
secret: "secret",
resave: true,
saveUninitialized: true,
})
);
app.use(passport.initialize());
app.use(passport.session());
app.listen(3010, () =>
console.log(`Example app listening at http://localhost:3010 🚀`)
);
})();完成登录逻辑
首先我们初始化一个登录路由:
app.get("/login", passport.authenticate("oidc"));
app.get(
"/auth/callback",
passport.authenticate("oidc", {
successRedirect: "/user",
failureRedirect: "/403",
})
);访问 /login 的时候调用 passport.authenticate,系统会跳转到 GenAuth OIDC Provider 的线上登录地址:

使用其中任意一种登录方式登录之后,浏览器会跳转到 http://localhost:3000/auth/callback(这是我们第一步中在应用详情中配置的回调链接),在这里会向 GenAuth 服务器获取用户信息,获取用户信息成功之后再跳转到 /user 路由。
完成展示用户信息逻辑
接下来我们来实现 /user 路由的逻辑,前面介绍到用户登录成功之后用户信息会被挂载到 req.user 上,所以这里我们添加以下简单的逻辑:
app.get("/user", (req, res) => {
res.send(req.user);
});
app.get("/session", (req, res) => {
res.send(req.session);
});访问 /user 可以看到当前登录用户的用户信息:

访问 /session 可以看到当前登录用户的 session:

完成退出登录逻辑
最后我们实现退出登录逻辑:
- 首先通过
req.session.destroy()清除当前应用的session; - 跳转到 OIDC 应用的退出登录链接。
const OIDC_LOGOUT_URL = "{{YOUR_APP_DOMAIN}}/login/profile/logout";
const LOGOUT_REDIRECT_URL = "http://localhost:3000";
app.get("/logout", (req, res) => {
req.session.destroy();
const logoutUrl = `${OIDC_LOGOUT_URL}?app_id=${OIDC_CLIENT_ID}&redirect_uri=${LOGOUT_REDIRECT_URL}`;
res.redirect(logoutUrl);
});在单页 Web 应用(SPA)中集成 GenAuth
单页 Web 应用(Single Page Application,简称 SPA)指的是一种 Web 应用或者网站的模型,它通过动态重写当前页面来与用户交互,而非传统的从服务器重新加载整个新页面。这种方法避免了页面之间切换打断用户体验,使应用程序更像一个桌面应用程序。在单页 Web 应用中,所有必要的代码(HTML、JavaScript 和 CSS)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态加载适当的资源并添加到页面。与单页 Web 应用的交互通常涉及到与后端服务器的动态通信。
在 SPA 应用中接入 GenAuth 最简单的方式是使用 GenAuth 提供的内嵌登录组件和 Javascript SDK 来进行登录和认证。本文以 React 项目为例。
获取应用 ID
登录 GenAuth 后,GenAuth 会为你创建一个默认用户池和应用,你也可以自己创建应用,在应用详情中,可以获取应用 ID,点击复制按钮复制即可:

集成 GenAuth 到你的 SPA 应用
安装 GenAuth 登录组件
yarn add @authing/react-ui-components
# OR
npm i @authing/react-ui-components --save@authing/react-ui-components 中有 GenAuth 提供的一些 React 组件和获取 AuthenticationClient 的 API,其中就包括 AuthingGuard 登录组件。
配置 AuthingGuard
import React from 'react'
import ReactDOM from 'react-dom'
import { Guard } from '@authing/react-ui-components'
// 引入 css 文件
import '@authing/react-ui-components/lib/index.min.css'
const App = () => {
const appId = 'AUTHING_APP_ID'
// 登录成功
const onLogin = (userInfo) => {
console.log(userInfo)
// 这里可以重定向到其他页面了
// ...
}
return <AuthingGuard appId={appId} onLogin={onLogin} />
}
ReactDOM.render(<App />, root)通过传入 appId,AuthingGuard 就可以展示登录框进行登录了。
退出登录
现在你已经可以登录了,同时需要一个方法使用户登出,可以通过 AuthenticationClient 实现。
// src/index.js
import { initAuthClient } from '@authing/react-ui-components'
// 在项目入口文件中初始化 AuthenticationClient
initAuthClient({
appId: 'AUTHING_APP_ID',
})import React from 'react'
import { getAuthClient } from '@authing/react-ui-components'
const LogoutButton = () => {
return <button onClick={() => getAuthClient().logout()}>退出</button>
}
export default LogoutButton获取用户信息
用户登录后,你可能还需要获取当前登录用户的用户信息。
// src/index.js
import { initAuthClient } from '@authing/react-ui-components'
// 在项目入口文件中初始化 AuthenticationClient
initAuthClient({
appId: 'AUTHING_APP_ID',
})import React, { useState, useEffect } from 'react'
import { getAuthClient } from '@authing/react-ui-components'
const UserInfo = () => {
const [user, setUser] = useState()
const [isAuthenticated, setIsAuthenticated] = useState(true)
useEffect(() => {
getAuthClient()
.getCurrentUser()
.then((userInfo) => {
if (userInfo) {
setUser(userInfo)
} else {
setIsAuthenticated(false)
}
})
}, [])
return isAuthenticated ? (
user ? (
<div>
<img src={user.photo} alt={user.username} />
<h2>{user.username}</h2>
<p>{user.email}</p>
</div>
) : (
<div>Loading...</div>
)
) : (
<h3>暂未登录</h3>
)
}
export default UserInfogetCurrentUser 能获取当前登录用户的信息,若未登录会返回 null
在移动端(iOS、Android)中集成 GenAuth
GenAuth 提供 Android SDK 和 iOS SDK 帮助开发者在移动 APP 中快速集成 GenAuth。
下面以 Android 应用的集成方式为例。
安装
- 下载 jar 包并将 jar 包导入 lib
Jar 包下载地址:
- https://download.authing.cn/packages/jar/commons-codec-1.15-rep.jar
- https://download.authing.cn/packages/jar/core.jar
将 Jar 包导入 lib,如下图所示:

- 配置
build.gradle
implementation "com.google.code.gson:gson:2.8.6"
implementation "com.squareup.okhttp3:okhttp:4.8.0"
implementation files('libs/core.jar')
implementation files('libs/commons-codec-1.15-rep.jar')- 安装 GenAuth Java/Kotlin SDK
详细的安装指引请见:GenAuth Java/Kotlin SDK 。
使用示例
Java
- 使用用户池 ID 初始化
AuthenticationClient。 - 调用
AuthenticationClient的方法。
// 使用 AppId 和 appHost 进行初始化
AuthenticationClient authentication = new AuthenticationClient(APP_ID, APP_HOST);
client.registerByEmail(new RegisterByEmailInput("xxx@qq.com", "123456")).enqueue(new cn.authing.core.http.Callback<cn.authing.core.types.User>() {
@Override
public void onSuccess(cn.authing.core.types.User user) {
}
@Override
public void onFailure(@Nullable GraphQLResponse.ErrorInfo errorInfo) {
}
});Kotlin
- 使用用户池 ID 初始化
AuthenticationClient。 - 调用
AuthenticationClient的方法。
val authenticationClient = AuthenticationClient("YOUR_USERPOOL_ID")
authenticationClient.registerByEmail(
RegisterByEmailInput(
"xxx@.qq.com",
"123456"
)
).enqueue(object : cn.authing.core.http.Callback<User> {
override fun onFailure(error: ErrorInfo?) {
}
override fun onSuccess(result: User) {
}
})用户注册登录
GenAuth Java SDK 支持手机号验证码、邮箱、用户名等多种注册登录方式,以手机号验证码登录为例:
- 发送验证码
String phone = "phone number";
authenticationClient.sendSmsCode(phone).execute();- 使用验证码登录
String phone = "phone number";
String code = "1234";
User user = authenticationClient.loginByPhoneCode(new LoginByPhoneCodeInput(phone, code)).execute();详细文档请见:用户注册登录 API 。
集成微信登录
你可以使用 AuthenticationClient 的 loginByWechat 方法,所需四个参数均为微信返回的参数:
| 字段名 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| code | REQUIRED | string | 微信返回给 APP 的 code |
| country | OPTIONAL | string | 微信返回给 APP 的 country |
| lang | OPTIONAL | string | 微信返回给 APP 的 lang |
| state | OPTIONAL | string | 微信返回给 APP 的 state |
val authenticationClient = AuthenticationClient("YOUR_USERPOOL_ID")
val code = "#returned code from wechat#";
authenticationClient.loginByWechat(code).enqueue(object: cn.authing.core.http.Callback<User> {
override fun onFailure(error: ErrorInfo?) {
}
override fun onSuccess(result: User) {
val user = result
}
})获取帮助
请访问 GenAuth 论坛。
GenAuth 体验期权益策略
背景
GenAuth 秉承着开发者友好的理念,愿意把满足开发者基本权益的功能永久免费开放给所有开发者使用。但此类免费版不仅会限制权益用量(例如允许的活跃用户数受限、可自建应用数受限),一些进阶功能也不可用(例如企业身份连接、单点登录、应用面板等)。为了让开发者更全面地了解 GenAuth 能力,充分体验 GenAuth 功能,选择与其需求匹配的权益,GenAuth 提出了「体验期」的概念,在限定时间内为开通体验期的开发者提供全部功能,实现全面体验。
体验期特征
体验期具有以下特征:
限期 30 天。
为 ToB、ToC、ToE 三种场景用户池分别提供体验期,每个场景仅能体验一次,不同场景提供不同权益和用量。
开放 GenAuth 当前用户池下所有权益,限制权益用量。
提供体验期倒计时提示。
管理员相关操作
管理员可以为用户池开通体验期,查看用户池内各版本权益对比,以及升级当前用户池版本。
开通体验期
新老用户都可以为不同场景下的用户池开通体验期,体验相应用户池下所有权益。本章节分别介绍新老用户如何开通体验期。
INFO
- 仅支持为新建用户池开通体验期,现有用户池不能直接开通体验期。
- 注意:体验期到期后,用户池若未升级版本,则关闭对应用户池的所有权益,不可以继续使用。
新用户开通体验期
要开通体验期,管理员需执行以下步骤:
- 新用户在官网按照提示注册,认证成功后点击 开始使用 按钮。

- 选择待开通体验期的用户池类型(此处以 ToB 为例),点击 创建用户池 按钮。提示已为当前用户池开启了体验期。
INFO
- 根据不同的用户使用场景,用户池可分为 ToE(企业员工)、ToB(客户)、ToC(终端用户)。一个账号可以在免费阶段为每个场景开通且仅能开通一次体验期。
- 页面下方默认勾选开启体验期提示,选择用户池并点击点击 创建用户池 即为创建的用户池默认开启 30 天体验期。若取消勾选,则会创建免费版用户池。

- 输入用户池名称,补全当前账户手机号信息,输入收到的验证码,点击 完成创建。

INFO
- 新用户需提供手机号,便于 GenAuth 了解您的使用体验,为您提供直达服务。
- 对于手机号注册用户,无需再补充手机号。
至此,完成新用户的注册并为创建的用户池开通体验期。新用户进入用户池首页,现在可以开始体验该用户池内所有权益。

老用户开通体验期
对于已经注册的用户,可以创建不同场景的用户池,并为其开通体验期。

要为老用户开通体验期,执行以下步骤:
点击页面左上角用户池下拉按钮。
点击 + 创建用户池。
选择用户池类型并点击 创建用户池 按钮。
输入用户池名,点击 完成创建。
INFO
系统会判断老用户是否已经注册了手机号,如已注册,则此处无需补全手机信息;否则,需要补全。

用户池体验期提示
开通体验期后,体验期提示出现在以下位置,借以帮助用户快速识别当前用户池已开通体验期,并提示用户体验期倒计时:
- 托管页所有页面顶部
INFO
对于每个场景的用户池,页面顶部都会提供相同的体验期策略提示:
- 显示体验期剩余天数(29->0 倒计时)。
- 体验期前 20 天,提示可关;超出 20 天,提示不可关闭。
- 点击 查看相应费用信息 可跳转至 设置->费用管理 页面查看用户池当前 版本信息(包括各用户池版本权益对比列表)、用量信息 及 订单管理 信息。
- 点击提示中 点击升级 按钮可跳转至 设置->费用管理->版本信息->版本升级 模块进行用户池版本升级。

- 用户池下拉列表

- 用户池管理页面

查看权益对比
版本信息
路径:设置->费用管理->版本信息->版本对比
每个场景用户池支持多种权益版本,不同版本提供不同权益和用量。体验期集成各版本所有权益,每种权益的用量采用各版本中最小用量(即阶梯式权益),不会超出高版本的限制。
在 费用管理 菜单下提供了用户池各版本间权益的对比,管理员可以在此查看各用户池版本所提供权益有哪些不同,以及各版本每个权益授权的用量有怎样的限制。
INFO
- 下图以 ToB 场景用户池为例,说明当体验期基于免费版时开放给用户的权益和相应用量。
- 如体验期内权益有更新,会为当前用户池同步更新,体验期策略不受影响。

| 序号 | 说明 |
|---|---|
| 1 | 表示当前权益限量,数字为被授权的用量。 |
| 2 | 表示当前功能是体验期权益,免费版本身无此权益。 |
| 3 | 表示当前权益不限量。 |
用量信息
路径:设置->费用管理->用量信息
管理员可以在 用量信息 标签页查看当前用户池体验期内享有的各权益详细用量信息。
权益卡片标有 体验期 表示,当前权益是超出免费版权益、为体验期试用的权益。

用户升级
体验期结束
体验期最长 30 天,如到期后用户池未升级,则体验期自动结束。
如 30 天体验期未满,用户即升级用户池版本,则体验期提前结束,开始升级版计费。此时,溢出权益(体验期享有的部分高级版权益)不可再用。
短信、邮件通知
创建当天,管理员会收到邮件及短信,通知已开通体验期。
到期前第七天、第三天、到期前一天、及到期当天,管理员会收到短信、邮件,提醒到期。
系统页面提示
在系统各页面顶部会在到期前十天始终作倒计时提示,不可关闭。
体验期到期未升级
新用户注册时,当前版本为免费版。体验期到期后,若没有升级版本,体验期用户池所有权益全部停用(包括该用户池的免费权益)。

- 管理员可以点击 联系我们,填写联系信息,描述问题。

也可点击 立即升级,跳转到 费用管理 页面,升级到高级别的版本,从而继续享有用户池权益。
还可点击弹出页面下方的「狠心离去,删除用户池」,从而删除当前用户池。
INFO
删除用户池后,体验期的所有数据会一并删除,不可恢复!
体验期到期后用户升级
路径:设置->费用管理->版本信息->版本升级
升级到基础版本
适用于:ToC、ToB 场景
体验期到期后,如果用户池从免费版升级到基础版,溢出权益将不再可用(但仍可见)。
要升级到基础版,执行以下步骤:
- 在 版本升级 模块点击 基础版本 所在卡片 立即升级 按钮。

- 在弹出的提示窗口浏览高级版拥有而基础版不支持的溢出权益。也可在弹窗中点击 各版本权益差异 查看各版本支持的权益详情(详见 版本对比)。

INFO
若仍需使用溢出权益,则可退出当前操作,执行 升级到高级版。
点击 升级为基础版 按钮。点击 暂不升级 则退出版本升级操作,放弃升级为基础版。
点击 前往实名认证。
INFO
依据相关法律规定,下单前需完成个人或企业实名认证。
- 选择认证类型:个人认证 或 企业认证,点击 开始认证。

- 填写认证信息,点击 提交认证。

INFO
个人实名认证

INFO
企业认证
系统提示认证成功,几秒后返回 费用管理->版本升级 页面。
- 再次点击 基础版本 所在卡片 立即升级 按钮。进入付费页面。

- 你可以在此选择新版本使用时长,点击 提交订单。
INFO
对于超过一年的使用时长,GenAuth 提供优惠政策:每满一年,免两个月的费用。
- 选择 支付方式,查看 服务协议 后勾选同意,点击 立即支付。
INFO
用户需要在两个小时内完成支付,逾期会关闭交易。
- 在弹出窗口扫码支付。
升级到高级版本
适用于:ToC、ToB、ToE 场景
升级到高级版后,所有权益都可用,且部分权益用量会提高。
INFO
体验期升级后,体验期内的用户数据仍可见。
要升级到高级版,执行以下步骤:
在 版本升级 模块点击 高级版本 所在卡片 立即升级 按钮。
若尚未进行实名认证,如 升级到基础版本步骤 5、6 所述进行个人 / 企业实名认证。
再次点击 高级版本 所在卡片 立即升级 按钮。进入付费页面。

- 参考 升级到基础版本步骤 8-10 进行付款。
至此,完成到高级版本的升级。
终端用户相关操作
体验期内
在体验期内,终端用户可以使用 GenAuth 能力登录应用,体验对应应用功能。
体验期外
体验期外,若管理员未升级,则提示体验到期,不能继续使用。无法登录应用。
控制台概览
控制台是你管理和配置所有 GenAuth 资源的地方,这篇文章会帮助你学会使用 GenAuth 控制台提升生产力!
在 GenAuth 控制台 中你可以对 GenAuth 的资源、用户等信息进行配置和修改。

INFO
控制台概览
以下会按照控制台左侧导航菜单 从上往下 介绍控制台每个模块:
模块 说明 概览 展示系统和用户的多种统计信息,包括:
- 展示总应用数量。
- 展示总用户数量。
- 展示登录和新增用户统计。
- 多种图形方式查看一段时间内用户的登录次数、数量变化、应用登录信息、用户分布等统计。 应用 可以在 应用 模块配置单点登录(SSO),包括:
- 集成第三方应用。
- 作为服务提供商(SP),将 APP集成至 Authing:
- 可配置应用基本信息、默认页面显示,为应用集成 OIDC / SAML2 / CAS / OAuth 2.0 / 协议。
- 配置登录方式。
- 进行访问授权。
- 自定义应用登录框、安全规则,身份品牌化。
- 进行租户配置。
- 作为身份提供商(IDP),对外提供认证。 身份源管理 连接第三方身份源,支持应用通过第三方身份源进行认证、授权登录,并支持客户自定义数据库用以存储用户数据,具体如下:
- 连接企业身份源(OIDC、SAML、办公应用如钉钉、企业微信)。
- 配置社会化登录。
- 自定义数据库。 用户管理 管理系统中的所有组织和用户信息,包括:
- 创建、管理用户。
- 创建、管理用户组。
- 创建、管理组织机构。
- 创建同步任务,实现组织信息和用户信息的上 / 下游同步。
- 使用 LDAP 协议查看、修改、增加和删除用户信息。
- 配置注册白名单。开启后,只有白名单内的用户才可进行注册。 权限管理 围绕资源、基于 RBAC(Role-Based Access Control,基于角色的访问控制)和 ABAC(Attribute-Based Access Control,基于属性的权限控制)进行精细化的权限管理,包括:
- 添加和管理资源,配置资源操作类型。
- 添加和管理角色,为角色分配用户、组织,并为角色授权资源操作。
- 通过一定的授权规则,将资源的访问、修改等权限授予某些主体。 安全设置 配置开发过程、密码设置、二次身份验证所涉及的安全策略,包括:
- 配置用户池级的基础、注册及登录安全规则。 安全域(Allowed Origins) 是允许从 JavaScript 向 Authing API 发出请求的 URL(通常与 CORS 一起使用)。 默认情况下,系统会允许你使用所有网址(*)。 如果需要,此字段允许你输入其他来源。 你可以通过逐行分隔多个有效 URL,并在子域级别使用通配符(例如:https://*.sample.com)。 验证这些 URL 时不考虑查询字符串和哈希信息,如果带上了查询字符串和哈希信息系统会自动忽略整个域名。
- 自定义密码强度、加密方法和密码轮换策略。
- 配置用户池级二次身份验证。 品牌化 可根据不同企业品牌需求自定义登录面板,配置信息补全。
- 配置登录框样式。
- 上传自定义 CSS。
- 配置登录注册用户协议。
- 配置消息邮件和短信提醒。 自动化 Authing 的 Pipeline、 Webhook、自定义密码函数极大地提升了认证过程中的灵活性和可扩展性,赋能用户自动化处理复杂场景。
- Pipeline
- Webhook 审计日志 在此可以查看用户操作日志和管理员日志。 设置 编辑或删除用户池,修改开发环境变量等:
- 用户池基础信息设置
- 费用管理在此可以服务升级以及查看订单详情。
- 扩展字段
- 环境变量环境变量就是一组 Key-Value 键值对(类似于操作系统的环境变量),你可以在环境变量中统一管理一些常量值,以便在 Pipeline、SAML 字段 Mapping、自定义数据等场景下使用。
- 协作管理员邀请用户池中的用户或 Authing 的官方用户池中的开发者,帮你管理该用户池,被授权的开发者将会在用户池列表页面中看到该用户池。