Skip to content
Go to Dashboard

快速开始

快速开始:认证你的第一个用户

概述

当使用 GenAuth 进行用户认证时,你不需要自己实现用户管理逻辑,所有的相关操作(如创建删除用户、配置登录流程、重置密码等)都可以通过 GenAuth 控制台托管登录页、API & SDK 完成。用户资料将被安全地存储在 GenAuth 云上的数据库中,你不需要额外保存一份用户资料,而是直接使用 GenAuth 中存储的用户信息实现你的业务需求。为此,需要先 将你的业务数据与 GenAuth 用户联表

使用 GenAuth 接入用户认证流程,一共有以下几种方式:

  1. 使用 GenAuth 托管登录页
  2. 使用 GenAuth 提供的内嵌登录组件,可以集成到你的 Web 和移动端项目中,你不需要自己实现登录表单 UI。
  3. 使用 API & SDK,GenAuth 提供 RESTFul 和 GraphQL 两种形式的 API 以及 10 余种语言或框架的 SDK,你可以基于此自定义 UI 和认证流程。

GenAuth 可以集成到标准 Web 应用、单页 Web 应用、客户端应用以及后端应用等各种场景中,你可以分别阅读不同场景的接入方式:

  1. 在标准 Web 应用中接入 GenAuth ?
  2. 在单页 Web 应用中接入 GenAuth ?
  3. 在客户端应用中接入 GenAuth ?

当用户成功登录之后,你还需要:

  1. 了解如何在后端鉴别当前用户的身份?
  2. 了解如何给用户授权角色、权限,以进行细粒度的权限控制?
  3. 了解如何实现退出操作?

使用托管登录页完成认证

GenAuth 托管登录页是最简单、安全的集成方式。这是因为登录流程由 GenAuth 维护,并由 GenAuth 保证安全。对于应用集成,建议使用 GenAuth 托管的登录流程。你的业务系统将用户重定向到 GenAuth 登录页,在此用户进行身份验证,然后重定向回在控制台配置的应用登录回调 URL。此设计被认为是安全性最佳实践。在自定义配置方面,托管模式提供了登录注册表单自定义配置,可通过控制台配置和 CSS 进行界面自定义。

本文档将会介绍如何使用 GenAuth 托管登录页快速实现一个完整的用户认证流程。

第一步:创建一个用户池

用户池 是你用户系统隔离的最小单位,你可以把不同场景的用户划分在不同的用户池。每个用户池下都可以有用户和应用程序,不同用户池之间的权限、应用、组织是完全隔离的。

  • 如果你还没有 GenAuth 开发者账号,你需要先在 控制台 注册一个 GenAuth 开发者账号。注册完成之后,会引导你创建自己的用户池。

  • 如果你已经有账号,想再创建一个用户池,可以点击左侧导航栏最上方的下拉按钮:

    选择用户池类型:

有关创建用户池详情,请参阅 新老用户如何创建用户池

第二步:创建一个应用

在控制台 应用->自建应用 页,你可以查看自己的应用列表:

有关创建和配置自建应用详情,请参阅 自建应用综述

应用创建成功后,点击右侧的 体验登录 按钮体验登录该应用:

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

有关创建和配置应用详情,请参阅 自建应用综述

第三步:创建一个用户

点击 立即注册,选择 密码注册,输入邮箱和密码,再次确认密码,勾选同意隐私和服务条款后,点击 注册 按钮。

注册成功之后,你可以在控制台的 用户列表 页(控制台 用户管理 菜单下)看到该用户。

第四步:体验登录

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

第五步:使用 Code 换取 Token

在实际应用中,你需要 修改回调地址为实际业务地址,该地址需要为一个后端地址。

获取到 code 之后,你需要使用 code 换取用户信息,Node.js 示例代码如下:

javascript
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_tokenaccess_token。简单来说,id_token 相当于用户的身份凭证;access_token 是允许访问资源的钥匙。有关 Access Token 和 ID Token 的区别,请参阅 Access Token vs Id Token

json
{
  "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

json
{
  "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 来获取用户的详细信息,示例代码如下:

javascript
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_tokenaccess_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-example

Code 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

javascript
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-sdk

Code snippet: init-sdk

使用 SDK 认证用户

以手机号验证码登录(如果用户账号不存在的话,会先创建一个账号)为例:

首先发送短信验证码

send-sms-code

Code snippet: send-sms-code

然后使用手机号验证码登录:

login-by-phone-code

Code snippet: login-by-phone-code

成功登录之后,你可以获取到该用户的用户信息,其中 token 为该用户的身份凭证,后续访问你后端资源的时候应该带上,然后在后端验证此 token 的身份。

验证用户 Token

用户信息的 token 字段为标准的 OIDC IdToken,你可以在后端使用应用的 ID 和 Secret 验证此 token

示例的 token 如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ZjIxNTFiZWFlNWE4YjRjZTZiMGJhZTkiLCJiaXJ0aGRhdGUiOiIiLCJmYW1pbHlfbmFtZSI6IiIsImdlbmRlciI6IiIsImdpdmVuX25hbWUiOiIiLCJsb2NhbGUiOiIiLCJtaWRkbGVfbmFtZSI6IiIsIm5hbWUiOiIiLCJuaWNrbmFtZSI6IiIsInBpY3R1cmUiOiJodHRwczovL3VzZXJjb250ZW50cy5hdXRoaW5nLmNuL2F1dGhpbmctYXZhdGFyLnBuZyIsInByZWZlcnJlZF91c2VybmFtZSI6InRlc3RAZXhhbXBsZS5jb20iLCJwcm9maWxlIjoiIiwidXBkYXRlZF9hdCI6IjIwMjEtMDEtMThUMDc6NDg6NTUuNzgxWiIsIndlYnNpdGUiOiIiLCJ6b25laW5mbyI6IiIsImFkZHJlc3MiOnsiY291bnRyeSI6IiIsInBvc3RhbF9jb2RlIjoiIiwicmVnaW9uIjoiIiwiZm9ybWF0dGVkIjoiIn0sInBob25lX251bWJlciI6bnVsbCwicGhvbmVfbnVtYmVyX3ZlcmlmaWVkIjpmYWxzZSwiZW1haWwiOiJ0ZXN0QGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJkYXRhIjp7InR5cGUiOiJ1c2VyIiwidXNlclBvb2xJZCI6IjVhOWZhMjZjZjg2MzVhMDAwMTg1NTI4YyIsImFwcElkIjoiNjAwNTNiNzQxNjQ3OGRlMmU4OGZhYjQzIiwiaWQiOiI1ZjIxNTFiZWFlNWE4YjRjZTZiMGJhZTkiLCJ1c2VySWQiOiI1ZjIxNTFiZWFlNWE4YjRjZTZiMGJhZTkiLCJfaWQiOiI1ZjIxNTFiZWFlNWE4YjRjZTZiMGJhZTkiLCJwaG9uZSI6bnVsbCwiZW1haWwiOiJ0ZXN0QGV4YW1wbGUuY29tIiwidXNlcm5hbWUiOiJ0ZXN0QGV4YW1wbGUuY29tIiwidW5pb25pZCI6bnVsbCwib3BlbmlkIjpudWxsLCJjbGllbnRJZCI6IjVhOWZhMjZjZjg2MzVhMDAwMTg1NTI4YyJ9LCJ1c2VycG9vbF9pZCI6IjVhOWZhMjZjZjg2MzVhMDAwMTg1NTI4YyIsImF1ZCI6IjYwMDUzYjc0MTY0NzhkZTJlODhmYWI0MyIsImV4cCI6MTYxMjE2NTg4OCwiaWF0IjoxNjEwOTU2Mjg4LCJpc3MiOiJodHRwczovL3NhbXBsZS1hcHAuYXV0aGluZy5jbi9vaWRjIn0.SNyGBffF-zBqDQFINGxUJZrWSAADHQhbEOsKvnH4SLg

你可以在该网站(国内用户可以访问此镜像站)中解码此 IdToken :

基本上所有语言都提供了检验 IdToken 的 Library,你可以选择自己熟悉的语言:

verify-id-token

Code snippet: verify-id-token

如果验证成功,你可以获取到该 id_token 的用户信息,其中 sub 字段为用户的 ID,aud 字段为应用的 ID,你可以点此了解 IdToken 每个字段的详细释义。

接下来

识别用户身份之后,你可能还需要对该用户进行权限管理,以判断用户是否对此 API 具备操作权限。

验证用户身份凭证(token)

当你的用户成功登录后,GenAuth 会为该用户签发一个 OIDC IdToken 作为身份凭证。验证方式请查看验证 Token 文档

一个示例解码过后的示例 OIDC IdToken 如下:

javascript
{
  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)授权其相关权限,简单来说,这相比直接授予用户权限,要更加灵活、高效、可扩展。

drawing

当使用 RBAC 时,通过分析系统用户的实际情况,基于共同的职责和需求,授予他们不同角色。你可以授予给用户一个或多个角色,每个角色具有一个或多个权限,这种 用户-角色、角色-权限 间的关系,让我们可以不用再单独管理单个用户,用户从授予的角色里面继承所需的权限。

以一个简单的场景(Gitlab 的权限系统)为例,用户系统中有 Admin、Maintainer、Operator 三种角色,这三种角色分别具备不同的权限,比如只有 Admin 具备创建代码仓库、删除代码仓库的权限,其他的角色都不具备。

我们授予某个用户「Admin」这个角色,他就具备了「创建代码仓库」和「删除代码仓库」这两个权限。

不直接给用户授权策略,是为了之后的扩展性考虑。比如存在多个用户拥有相同的权限,在分配的时候就要分别为这几个用户指定相同的权限,修改时也要为这几个用户的权限进行一一修改。有了角色后,我们只需要为该角色制定好权限后,给不同的用户分配不同的角色,后续只需要修改角色的权限,就能自动修改角色内所有用户的权限。

什么是基于属性的访问控制(ABAC)

基于属性的访问控制(Attribute-Based Access Control,简称 ABAC)是一种灵活的授权模型,通过一个或一组属性来控制是否有对操作对象的权限。 ABAC 属性通常来说分为四类:用户属性(如用户年龄),环境属性(如当前时间),操作属性(如读取)和对象属性(如一篇文章,又称资源属性),所以理论上能够实现非常灵活的权限控制:

在 ABAC 权限模型下,你可以轻松地实现以下权限控制逻辑:

  1. 授权编辑 A 具体某本书的编辑权限;
  2. 当一个文档的所属部门跟用户的部门相同时,用户可以访问这个文档;
  3. 当用户是一个文档的拥有者并且文档的状态是草稿,用户可以编辑这个文档;
  4. 早上九点前禁止 A 部门的人访问 B 系统;
  5. 在除了上海以外的地方禁止以管理员身份访问 A 系统;

上述的逻辑中有几个共同点:

  1. 具体到某一个而不是某一类资源;
  2. 具体到某一个操作;
  3. 能通过请求的上下文(如时间、地理位置、资源 Tag)动态执行策略;

如果浓缩到一句话,你可以细粒度地授权在何种情况下对某个资源具备某个特定的权限。

授权模式介绍

GenAuth 支持两种授权模式:

  1. 通过基于 OAuth 2.0 流程中的授权码模式
  2. 通过权限 API 对用户进行授权管理。

借助 GenAuth 实现权限模型

下面我们以调用权限 API 的模式为例。

创建角色

你可以使用 GenAuth 控制台创建角色:在权限管理 - 角色管理中,点击添加角色按钮:

  • 角色 code: 该角色的唯一标志符,只允许包含英文字母、数字、下划线 _、横线 -,这里我们填 admin。
  • 角色描述:该角色的描述信息,这里我们填管理员。

创建好三个角色:

你也可以使用 API & SDK 创建角色,详情请见角色 Management SDK

授权用户角色

在角色详情页面,你可以将此角色授权给用户。你可以通过用户名、手机号、邮箱、昵称搜索用户:

选择用户之后点击确认,你可以查看被授权此角色的用户列表。

你也可以使用 API & SDK 给用户授予角色,详情请见角色 Management SDK

在后端通过用户角色控制权限

当用户成功认证、获取到 Token 之后,你可以解析到当前用户的 ID,接下来你可以使用我们提供的 API & SDK 在后端获取该用户被授予的角色,这里以 Node.js 为例:

首先获取用户的被授予的所有角色列表:

javascript
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 这个角色:

javascript
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,详情请点击此

javascript
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
javascript
const { totalCount, list } = await managementClient.acl.isAllowed(
  'USER_ID',
  'repository:123',
  'repository:Delete'
)

GenAuth 策略引擎会根据你配置的权限策略,动态执行策略,最后返回 true 或者 false,你只需要根据返回值就能判断用户是否具备操作权限。

总结

本文从最简单的 RBAC 权限模型开始,再在此之上实现了如何进行更细粒度、动态的 ABAC 权限模型,且整个过程是渐进地,你可以随着业务的复杂性不断变大,逐步地迁移到 ABAC 权限模型。

退出登录

GenAuth 支持多种退出方式:

从个人中心退出

终端用户可以访问 https://应用域名.authing.cn/u 进入个人中心,点击右上角的头像,点击退出。

从前端退出

引导你的终端用户访问 https://应用域名.authing.cn/login/profile/logout?redirect_uri={{CALLBACK_URL}} 进行退出,redirect_uri 可以填写一个退出后的回调地址,例如可以跳转到你的业务首页。

注意 ⚠️:你需要使用 encodeURIComponent 对回调链接进行 URL Encode。

从后端登出

如果你需要在后端退出一个 GenAuth 用户,需要访问以下接口:

  • 接口说明:用户池管理员在后端将 GenAuth 用户退出登录。
  • 接口地址:POST https://<你的应用域名>.authing.cn/api/v2/applications/:appId/kick-active-users
  • 请求头:
参数类型是否必填描述
x-authing-userpool-idstring用户池 ID。
Authorizationstring用户池管理员 token
  • 请求参数:
参数类型是否必填描述
userIdsstring[]用户 ID 数组。
appIdstring应用 ID。
  • 返回数据:
json
{
  "code": 200,
  "message": "强制下线成功"
}

强制用户下线

用户池管理员可以通过控制台 > 应用 > 登录态管理,强制让用户下线。

接下来你可能需要

看到这里你已经对如何使用 GenAuth 有了一个基本的了解了,接下来你可以:

  1. 了解如何为你的应用添加社会化登录
  2. 在应用之间实现单点登录
  3. 对用户进行权限管理
  4. 了解如何管理用户目录
  5. 如果你有原有用户系统中的用户需要导入到 GenAuth,请务必阅读此部分的指引。

在标准 Web 应用中集成 GenAuth

本文以 Node.js Web 框架 Express 为例,介绍如何在传统的 Web 项目(如 Express MVC 、Django、PHP Laravel 等)中快速接入 GenAuth,实现登录、退出、获取用户信息等功能。

这里一共牵涉到三方:终端用户浏览器、应用服务器、 GenAuth 服务器,完整流程如下:

  1. 终端用户浏览器请求应用服务,发现用户未登录,跳转到 GenAuth 托管的登录页。
  2. 用户在此登录页完成登录之后,终端用户浏览器会在请求参数中携带授权码 (Authorization Code) 等数据跳转到应用服务器预先配置好的回调链。
  3. 应用服务器使用授权码 (Authorization Code) 向 GenAuth 服务器请求换取用户信息。
  4. 应用服务器获取到用户信息之后,建立与终端用户的会话。
  5. 终端用户得到登录成功提示,认证流程完成。

流程图如下所示:

在 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-clientpassportjs

bash
yarn add express express-session passport openid-client

Java 开发者可以使用 Spring 框架的 spring-security,详细接入流程请见文档

初始化

在项目的最开始我们需要初始化 openid-clientIssuer,初始化参数如下:

  • 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 官方文档

javascript
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);
});

详细示例代码如下:

javascript
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 🚀`)
  );
})();

完成登录逻辑

首先我们初始化一个登录路由:

javascript
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 上,所以这里我们添加以下简单的逻辑:

javascript
app.get("/user", (req, res) => {
  res.send(req.user);
});
app.get("/session", (req, res) => {
  res.send(req.session);
});

访问 /user 可以看到当前登录用户的用户信息:

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

完成退出登录逻辑

最后我们实现退出登录逻辑:

  1. 首先通过 req.session.destroy() 清除当前应用的 session
  2. 跳转到 OIDC 应用的退出登录链接。
javascript
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 登录组件

bash
yarn add @authing/react-ui-components

 # OR

npm i @authing/react-ui-components --save

@authing/react-ui-components 中有 GenAuth 提供的一些 React 组件和获取 AuthenticationClient 的 API,其中就包括 AuthingGuard 登录组件。

配置 AuthingGuard

js
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)

通过传入 appIdAuthingGuard 就可以展示登录框进行登录了。

退出登录

现在你已经可以登录了,同时需要一个方法使用户登出,可以通过 AuthenticationClient 实现。

js
// src/index.js

import { initAuthClient } from '@authing/react-ui-components'
// 在项目入口文件中初始化 AuthenticationClient
initAuthClient({
  appId: 'AUTHING_APP_ID',
})
js
import React from 'react'
import { getAuthClient } from '@authing/react-ui-components'

const LogoutButton = () => {
  return <button onClick={() => getAuthClient().logout()}>退出</button>
}

export default LogoutButton

获取用户信息

用户登录后,你可能还需要获取当前登录用户的用户信息。

js
// src/index.js

import { initAuthClient } from '@authing/react-ui-components'
// 在项目入口文件中初始化 AuthenticationClient
initAuthClient({
  appId: 'AUTHING_APP_ID',
})
js
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 UserInfo

getCurrentUser 能获取当前登录用户的信息,若未登录会返回 null

在移动端(iOS、Android)中集成 GenAuth

GenAuth 提供 Android SDKiOS SDK 帮助开发者在移动 APP 中快速集成 GenAuth。

下面以 Android 应用的集成方式为例。

安装

  1. 下载 jar 包并将 jar 包导入 lib

Jar 包下载地址:

将 Jar 包导入 lib,如下图所示:

  1. 配置 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')
  1. 安装 GenAuth Java/Kotlin SDK

详细的安装指引请见:GenAuth Java/Kotlin SDK

使用示例

Java

  • 使用用户池 ID 初始化 AuthenticationClient
  • 调用 AuthenticationClient 的方法。
java
// 使用 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 的方法。
kotlin
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 支持手机号验证码、邮箱、用户名等多种注册登录方式,以手机号验证码登录为例:

  1. 发送验证码
java
String phone = "phone number";
authenticationClient.sendSmsCode(phone).execute();
  1. 使用验证码登录
java
String phone = "phone number";
String code = "1234";
User user = authenticationClient.loginByPhoneCode(new LoginByPhoneCodeInput(phone, code)).execute();

详细文档请见:用户注册登录 API

集成微信登录

你可以使用 AuthenticationClientloginByWechat 方法,所需四个参数均为微信返回的参数:

字段名是否必填类型说明
codeREQUIREDstring微信返回给 APP 的 code
countryOPTIONALstring微信返回给 APP 的 country
langOPTIONALstring微信返回给 APP 的 lang
stateOPTIONALstring微信返回给 APP 的 state
kotlin
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

  • 仅支持为新建用户池开通体验期,现有用户池不能直接开通体验期。
  • 注意:体验期到期后,用户池若未升级版本,则关闭对应用户池的所有权益,不可以继续使用。

新用户开通体验期

要开通体验期,管理员需执行以下步骤:

  1. 新用户在官网按照提示注册,认证成功后点击 开始使用 按钮。

  1. 选择待开通体验期的用户池类型(此处以 ToB 为例),点击 创建用户池 按钮。提示已为当前用户池开启了体验期。

INFO

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

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

INFO

  • 新用户需提供手机号,便于 GenAuth 了解您的使用体验,为您提供直达服务。
  • 对于手机号注册用户,无需再补充手机号。

至此,完成新用户的注册并为创建的用户池开通体验期。新用户进入用户池首页,现在可以开始体验该用户池内所有权益。

老用户开通体验期

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

要为老用户开通体验期,执行以下步骤:

  1. 点击页面左上角用户池下拉按钮。

  2. 点击 + 创建用户池

  3. 选择用户池类型并点击 创建用户池 按钮。

  4. 输入用户池名,点击 完成创建

INFO

系统会判断老用户是否已经注册了手机号,如已注册,则此处无需补全手机信息;否则,需要补全。

用户池体验期提示

开通体验期后,体验期提示出现在以下位置,借以帮助用户快速识别当前用户池已开通体验期,并提示用户体验期倒计时:

  • 托管页所有页面顶部

INFO

对于每个场景的用户池,页面顶部都会提供相同的体验期策略提示:

  • 显示体验期剩余天数(29->0 倒计时)。
  • 体验期前 20 天,提示可关;超出 20 天,提示不可关闭。
  • 点击 查看相应费用信息 可跳转至 设置->费用管理 页面查看用户池当前 版本信息(包括各用户池版本权益对比列表)、用量信息订单管理 信息。
  • 点击提示中 点击升级 按钮可跳转至 设置->费用管理->版本信息->版本升级 模块进行用户池版本升级。
  • 用户池下拉列表
  • 用户池管理页面

查看权益对比

版本信息

路径:设置->费用管理->版本信息->版本对比

每个场景用户池支持多种权益版本,不同版本提供不同权益和用量。体验期集成各版本所有权益,每种权益的用量采用各版本中最小用量(即阶梯式权益),不会超出高版本的限制。

费用管理 菜单下提供了用户池各版本间权益的对比,管理员可以在此查看各用户池版本所提供权益有哪些不同,以及各版本每个权益授权的用量有怎样的限制。

INFO

  • 下图以 ToB 场景用户池为例,说明当体验期基于免费版时开放给用户的权益和相应用量。
  • 如体验期内权益有更新,会为当前用户池同步更新,体验期策略不受影响。
序号说明
1表示当前权益限量,数字为被授权的用量。
2表示当前功能是体验期权益,免费版本身无此权益。
3表示当前权益不限量。

用量信息

路径:设置->费用管理->用量信息

管理员可以在 用量信息 标签页查看当前用户池体验期内享有的各权益详细用量信息。

权益卡片标有 体验期 表示,当前权益是超出免费版权益、为体验期试用的权益。

用户升级

体验期结束

  • 体验期最长 30 天,如到期后用户池未升级,则体验期自动结束。

  • 如 30 天体验期未满,用户即升级用户池版本,则体验期提前结束,开始升级版计费。此时,溢出权益(体验期享有的部分高级版权益)不可再用。

短信、邮件通知

创建当天,管理员会收到邮件及短信,通知已开通体验期。

到期前第七天、第三天、到期前一天、及到期当天,管理员会收到短信、邮件,提醒到期。

系统页面提示

在系统各页面顶部会在到期前十天始终作倒计时提示,不可关闭。

体验期到期未升级

新用户注册时,当前版本为免费版。体验期到期后,若没有升级版本,体验期用户池所有权益全部停用(包括该用户池的免费权益)。

  • 管理员可以点击 联系我们,填写联系信息,描述问题。
  • 也可点击 立即升级,跳转到 费用管理 页面,升级到高级别的版本,从而继续享有用户池权益。

  • 还可点击弹出页面下方的「狠心离去,删除用户池」,从而删除当前用户池。

INFO

删除用户池后,体验期的所有数据会一并删除,不可恢复!

体验期到期后用户升级

路径:设置->费用管理->版本信息->版本升级

升级到基础版本

适用于:ToC、ToB 场景

体验期到期后,如果用户池从免费版升级到基础版,溢出权益将不再可用(但仍可见)。

要升级到基础版,执行以下步骤:

  1. 版本升级 模块点击 基础版本 所在卡片 立即升级 按钮。
  1. 在弹出的提示窗口浏览高级版拥有而基础版不支持的溢出权益。也可在弹窗中点击 各版本权益差异 查看各版本支持的权益详情(详见 版本对比)。

INFO

若仍需使用溢出权益,则可退出当前操作,执行 升级到高级版

  1. 点击 升级为基础版 按钮。点击 暂不升级 则退出版本升级操作,放弃升级为基础版。

  2. 点击 前往实名认证

INFO

依据相关法律规定,下单前需完成个人或企业实名认证。

  1. 选择认证类型:个人认证企业认证,点击 开始认证
  1. 填写认证信息,点击 提交认证

INFO

个人实名认证

INFO

企业认证

系统提示认证成功,几秒后返回 费用管理->版本升级 页面。

  1. 再次点击 基础版本 所在卡片 立即升级 按钮。进入付费页面。
  1. 你可以在此选择新版本使用时长,点击 提交订单

INFO

对于超过一年的使用时长,GenAuth 提供优惠政策:每满一年,免两个月的费用。

  1. 选择 支付方式,查看 服务协议 后勾选同意,点击 立即支付

INFO

用户需要在两个小时内完成支付,逾期会关闭交易。

  1. 在弹出窗口扫码支付。
升级到高级版本

适用于:ToC、ToB、ToE 场景

升级到高级版后,所有权益都可用,且部分权益用量会提高。

INFO

体验期升级后,体验期内的用户数据仍可见。

要升级到高级版,执行以下步骤:

  1. 版本升级 模块点击 高级版本 所在卡片 立即升级 按钮。

  2. 若尚未进行实名认证,如 升级到基础版本步骤 5、6 所述进行个人 / 企业实名认证。

  3. 再次点击 高级版本 所在卡片 立即升级 按钮。进入付费页面。

  1. 参考 升级到基础版本步骤 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 的官方用户池中的开发者,帮你管理该用户池,被授权的开发者将会在用户池列表页面中看到该用户池。