跳到正文

常见问题 FAQ ​

如何获取用户池 ID(UserPool Id)和用户池密钥(UserPool Secret)? ​

在控制台的设置 -> 基础设置 -> 密钥管理页面,可以获取到用户池 ID(UserPoolId)和用户池密钥(UserPool Secret),如下图所示:

drawing

如何获取应用 ID (AppID) 和应用密钥(AppSecret) ​

在控制台 > 应用 > 自建应用 页面,你可以查看到自己的所有应用,点击某个应用卡片进入应用详情,如图所示,可在「端点信息」卡片处找到APP ID 和 APP Secret:

下滑找到「认证配置」卡片,在认证地址一栏可以找到该应用的域名(AppHost),如图所示:

如何验证用户身份凭证(token) ​

验证 Token 分为两种模式:本地验证与使用 GenAuth 在线验证。我们建议在本地验证 JWT Token,因为可以节省你的服务器带宽并加快验证速度。你也可以选择将 Token 发送到 GenAuth 的验证接口由 GenAuth 进行验证并返回结果,但这样会造成网络延迟,而且在网络拥塞时可能会有慢速请求。

以下是本地验证和在线验证的优劣对比:

验证速度代码复杂度可靠程度
在线验证慢 🐢简单单点故障风险
本地验证快 🐇一般分布式

本地验证 ​

使用应用密钥验证 HS256 算法签名的 Token ​

如果你直接调用了登录方法(loginByEmail、loginByPhone、loginByUsername)或使用了 OIDC 授权,且 IdToken 签名算法类型设置为 HS256 时请使用此方式验证 Token。

可以在控制台 > 应用 > 应用详情中获取到密钥,如下图所示:

以下验证合法性的代码以 Node 为例(需要安装 JSON Web Token)。

javascript
const jwt = require('jsonwebtoken');
try {
  let decoded = jwt.verify('JSON Web Token from client', 'your_secret'),
    expired = Date.parse(new Date()) / 1000 > decoded.exp;
  if (expired) {
    // 过期
  } else {
    // 合法也没过期,正常放行
  }
} catch (error) {
  // 不合法
}

为了避免在客户端暴露应用密钥,请在服务端通过应用密钥验证 id_token 的合法性。

使用应用公钥验证 RS256 算法签名的 IdToken ​

如果使用 RS256 签名算法,需要使用公钥验证签名。GenAuth 将使用应用的私钥进行签名,请使用 https://<应用域名>.authing.cn/oidc/.well-known/jwks.json 中的公钥来验证签名。GenAuth 颁发的 access_token 和 id_token 都可以使用上述公钥进行验签。

如果你使用 javascript,可以使用 jose 库来验证 RS256 签名:

请使用 v2.x.x 或以下版本的 jose 库,新版 jose 库和本代码示例不兼容。

javascript
const jose = require('jose');
// 下面的参数内容是将 https://<应用域名>.authing.cn/oidc/.well-known/jwks.json 返回的内容原封不动复制过来
const keystore = jose.JWKS.asKeyStore({
  keys: [
    {
      e: 'AQAB',
      n:
        'o8iCY52uBPOCnBSRCr3YtlZ0UTuQQ4NCeVMzV7JBtH-7Vuv0hwGJTb_hG-BeYOPz8i6YG_o367smV2r2mnXbC1cz_tBfHD4hA5vnJ1eCpKRWX-l6fYuS0UMti-Bmg0Su2IZxXF9T1Cu-AOlpgXFC1LlPABL4E0haHO8OwQ6QyEfiUIs0byAdf5zeEHFHseVHLjsM2pzWOvh5e_xt9NOJY4vB6iLtD5EIak04i1ND_O0Lz0OYbuV0KjluxaxoiexJ8kGo9W1SNza_2TqUAR6hsPkeOwwh-oHnNwZg8OEnwXFmNg-bW4KiBrQEG4yUVdFGENW6vAQaRa2bJX7obn4xCw',
      kty: 'RSA',
      alg: 'RS256',
      use: 'sig',
      kid: 'TfLOt3Lbn8_a8pRMuessamqj-o3DBCs1-owHLQ-VMqQ',
    },
  ],
});
// 选项中 issuer 的内容是 https://<应用域名>.authing.cn/oidc,audience 的内容是 应用 ID
// id_token 很长,请向右滑动 ->
const res = jose.JWT.IdToken.verify(
  'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlRmTE90M0xibjhfYThwUk11ZXNzYW1xai1vM0RCQ3MxLW93SExRLVZNcVEifQ.eyJzdWIiOiI1ZjcxOTk0NjUyNGVlMTA5OTIyOTQ5NmIiLCJiaXJ0aGRhdGUiOm51bGwsImZhbWlseV9uYW1lIjpudWxsLCJnZW5kZXIiOiJVIiwiZ2l2ZW5fbmFtZSI6bnVsbCwibG9jYWxlIjpudWxsLCJtaWRkbGVfbmFtZSI6bnVsbCwibmFtZSI6bnVsbCwibmlja25hbWUiOm51bGwsInBpY3R1cmUiOiJodHRwczovL2ZpbGVzLmF1dGhpbmcuY28vdXNlci1jb250ZW50cy9waG90b3MvOWE5ZGM0ZDctZTc1Ni00NWIxLTgxZDgtMDk1YTI4ZTQ3NmM2LmpwZyIsInByZWZlcnJlZF91c2VybmFtZSI6InRlc3QxIiwicHJvZmlsZSI6bnVsbCwidXBkYXRlZF9hdCI6IjIwMjAtMDktMzBUMDc6MTI6MTkuNDAxWiIsIndlYnNpdGUiOm51bGwsInpvbmVpbmZvIjpudWxsLCJlbWFpbCI6InRlc3QxQDEyMy5jb20iLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInBob25lX251bWJlciI6bnVsbCwicGhvbmVfbnVtYmVyX3ZlcmlmaWVkIjpmYWxzZSwibm9uY2UiOiJFNjViMVFvVVl0IiwiYXRfaGFzaCI6IkIzSWdPWUREYTBQejh2MV85cVpyQXciLCJhdWQiOiI1ZjE3YTUyOWY2NGZiMDA5Yjc5NGEyZmYiLCJleHAiOjE2MDE0NTM1NTgsImlhdCI6MTYwMTQ0OTk1OSwiaXNzIjoiaHR0cHM6Ly9vaWRjMS5hdXRoaW5nLmNuL29pZGMifQ.Z0TweYr9bCdYNJREVdvbJYcjXSfSsSNHBMqxTJeW-bnza0IIpBpEEVxlDG0Res6FZbcVzsQZzfJ9pj_nFgLjZxUUxv7Tpd13Sq_Ykg2JKepPf3-uoFqbORym07QEj4Uln0Quuh094MTb7z6bZZBEOYBac46zuj4uVp4vqk5HtCUSB4ASOAxwi7CeB1tKghISHz6PDcf6XJe_btHdzX1dparxtML-KvPxjpcHlt5emN88lpTAOX7Iq0EhsVE3PKrIDfCkG8XlL5y9TIW2Dz2iekcZ5PV17M35G6Dg2Q07Y_Apr18_oowOiQM5m_EbI90ist8CiqO9kBKreCOLMzub4Q',
  keystore,
  {
    issuer: 'https://oidc1.authing.cn/oidc',
    audience: '5f17a529f64fb009b794a2ff',
  }
);
console.log(res);

输出结果:

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'
}

在线验证 ​

在线验证 OIDC AccessToken ​

只有 access_token 和 refresh_token 可以检测状态,id_token 无法检测。

  • 接口说明:检查签发的 access_token 或 refresh_token 有效状态。
  • 接口地址:POST https://<你的应用域名>.authing.cn/oidc/token/introspection
  • 请求头:
参数类型是否必填描述
Content-Typestring是application/x-www-form-urlencoded
  • 请求参数:
参数类型是否必填描述
tokenstring是要检验的 token 值。
token_type_hintstring是要检验的 token 类型,可选值为 access_token、refresh_token。
client_idstring否应用 ID,在控制台配置检验 token 身份验证方式为 client_secret_post 和 none 时必填。
client_secretstring否应用 Secret,在控制台配置检验 token 身份验证方式为 client_secret_post 时必填。
  • 返回数据:

当 token 有效时返回以下格式内容

json
{
  "active": true,
  "sub": "5f623f30d85f84c58f141777", // subject 的缩写,为用户 ID
  "client_id": "5d01e389985f81c6c1dd31de",
  "exp": 1600634105,
  "iat": 1600274405,
  "iss": "https://oidc1.authing.cn",
  "jti": "hoV44FPNR-_EfxTP7s7vw",
  "scope": "openid profile email phone offline_access",
  "token_type": "Bearer"
}

当 token 无效时(过期,错误,被撤回)返回以下格式内容

json
{
  "active": false
}

在线验证 OIDC IdToken ​

本接口可以检测 access_token 和 id_token 的有效性,refresh_token 无法检测。

  • 接口说明:检查签发的 access_token 或 id_token 有效状态。
  • 接口地址:GET https://<你的应用域名>.authing.cn/api/v2/oidc/validate_token
  • 请求参数:
参数类型是否必填描述
access_tokenstring否AccessToken 的内容。
id_tokenstring否IdToken 的内容。
  • 返回数据:

access_token 或 id_token 合法时,返回 access_token / id_token 解码后的的内容

json
// access_token 检验后的返回结果:
{
    "jti": "K5TYewNhvdGBdHiRifMyW",
    "sub": "5f64afd1ad501364e3b43c1e", // subject 的缩写,为用户 ID
    "iat": 1601456894,
    "exp": 1601460494,
    "scope": "openid profile email phone",
    "iss": "https://oidc1.authing.cn/oidc",
    "aud": "5f17a529f64fb009b794a2ff"
}

// id_token 检验后的返回结果:
{
    "sub": "5f64afd1ad501364e3b43c1e", // subject 的缩写,为用户 ID
    "birthdate": null,
    "family_name": null,
    "gender": "U",
    "given_name": null,
    "locale": null,
    "middle_name": null,
    "name": null,
    "nickname": null,
    "picture": "https://usercontents.authing.cn/authing-avatar.png",
    "preferred_username": "test1",
    "profile": null,
    "updated_at": "2020-09-27T06:06:29.853Z",
    "website": null,
    "zoneinfo": null,
    "email": "test1@123.com",
    "email_verified": false,
    "phone_number": null,
    "phone_number_verified": false,
    "nonce": "CQsguqUdl7",
    "at_hash": "10iOtwuTNtyQLzlNYXAHeg",
    "aud": "5f17a529f64fb009b794a2ff",
    "exp": 1601460494,
    "iat": 1601456894,
    "iss": "https://oidc1.authing.cn/oidc",
}

access_token 或 id_token 非法时,返回以下错误信息

javascript
{
  code: 400,
  message: 'id_token 不合法',
}

{
  code: 400,
  message: 'access_token 不合法',
}

在线验证 OAuth2 AccessToken ​

  • 接口说明:可以检验 access_token 和 refresh_token
  • 接口地址:POST https://<你的应用域名>.authing.cn/oauth/token/introspection
  • 请求头:
参数类型是否必填描述
Content-Typestring是application/x-www-form-urlencoded
Authorizationstring否在控制台应用配置详情,「配置 OAuth2.0 身份提供商」选项卡中,配置检验 token 身份验证方式为 client_secret_basic 时必填,形式为:Basic base64(应用 ID + ':' + 应用 Secret)
  • 请求参数:
参数类型是否必填描述
tokenstring是要检验的 token 值。
token_type_hintstring是要检验的 token 类型,可选值为 access_token
client_idstring否应用 ID,在控制台应用配置详情,「配置 OAuth2.0 身份提供商」选项卡中,配置检验 token 身份验证方式为 client_secret_post 和 none 时必填
client_secretstring否应用 Secret,在控制台应用配置详情,「配置 OAuth2.0 身份提供商」选项卡中,配置撤回 token 身份验证方式为 client_secret_post 时必填。
  • 返回数据:

当 token 有效时返回以下格式内容

json
{
  "active": true,
  "sub": "5dc10851ebafee30ce3fd5e9", // subject 的缩写,为用户 ID
  "client_id": "5cded22b4efab31716fa665f",
  "exp": 1602423020,
  "iat": 1602419420,
  "iss": "https://core.authing.cn/oauth",
  "jti": "SaPg48dbO66T77xkT8wy0",
  "scope": "user",
  "token_type": "Bearer"
}

当 token 无效时(过期,错误,被撤回)返回以下格式内容

json
{
  "active": false
}

使用统一域名的用户池 ​

默认情况下,在 GenAuth 创建的用户池不使用统一的三级域名。但在某些特殊场景下,你可能会需要在整个用户池中使用统一的域名(即用户池中的所有应用均使用统一的、用户池级别的域名)。

要明确对此功能的实际需求,请按照以下步骤比对你的使用场景进行选择:

第一步:了解什么是统一域名 ​

GenAuth 的用户池中存在多种类型的应用,包括:自建应用、集成应用,以及可以收纳这两种应用进行 单点登录(SSO) 的应用面板。默认状态下, GenAuth 用户池中以上各种类型的应用使用独立的三级域名(xxx.authig.cn),你可以独立地修改任何一个自建应用以及应用面板的认证地址。

与此对比,统一域名指的是同一个用户池中各种类型的应用均使用同样的三级域名。创建此类用户池之后,你可以在用户池 设置->基础设置->基础信息 标签页对此用户池统一的三级域名进行修改。你的修改将会对该用户池中的所有应用同时生效,不同应用之间将会通过在认证地址后拼接 App ID 的方式进行区分(xxx.authing.cn/APP_ID)。

第二步:判断你是否需要使用统一域名 ​

什么情况下需要使用统一域名? ​

  • 你希望用户池中所有应用的三级域名能够被统一修改。

  • 你希望在整个用户池中使用自定义域名功能。

    • 应用面板使用自定义域名。

    • 自建应用使用自定义域名。

什么情况不建议使用统一域名? ​

  • 你希望每个应用的三级域名能够被自定义。

  • 你接受使用 GenAuth 默认的二级域名(即 .authing.cn)。

第三步:创建一个统一域名的用户池 ​

  1. 在创建用户池时打开 高级选项。

  2. 打开 所有应用使用统一域名 开关。

第四步:统一域名用户池的常见操作 ​

  • 在新建的统一域名的用户池中配置自定义域名:

    • 配置方法:按照 自定义域名 中的引导完成配置。

    • 实现效果:应用面板、用户池中的所有自建应用和集成应用均使用统一的自定义域名。

  • 将已有用户池切换为使用统一域名:

    • 新建统一域名的用户池,迁移已有数据。

    • 联系 GenAuth 售后服务人员寻求技术支持,或登录 GenAuth 控制台 提交工单。

如何识别用户来源 ​

如果你使用 托管登录页 或者 嵌入登录组件,GenAuth 支持自动识别请求参数将用户来源写入到用户的自定义字段。同时,GenAuth 提供的 SDK 也可以在登录注册时将注册来源信息写入到用户的自定义字段,从而达到识别用户来源的目的。

使用托管登录页面 ​

GenAuth 托管登录页 模式被认为是最简单,最安全的集成方式。这是因为登录流程由 GenAuth 维护,并由 GenAuth 保持安全。对于大多数集成,建议使用 GenAuth 托管的登录流程。你的业务系统将用户重定向到 GenAuth,在此用户进行身份验证,然后重定向回在控制台配置的应用回调连接。

在托管登录页面中识别用户来源,可以分为以下几步。

  1. 在 GenAuth 控制台定义一个用户自定义字段(如 source),用于存储用户的来源数据,详情请见 添加自定义用户字段。
  2. 访问应用域名的时候带上指定的 query 参数,如 https://your-app.authing.cn?source=someWhere。
  3. 当用户登录注册的时候,GenAuth 将会将此数据写入到用户的自定义字段中。
  4. 之后你可以使用 GenAuth 提供的 SDK 管理用户的自定义字段,详情请见 SDK - 管理自定义数据。

使用嵌入登录组件 ​

GenAuth 登录组件(Guard) 是一种可嵌入的登录表单,可根据你的需求进行配置,建议用于单页面应用程序。Guard 可以集成到你的 React、Vue.js、Angular 以及原生 JavaScript 项目中,你可以借助此组件快速实现登录认证流程。

在嵌入登录组件中识别用户来源,可以分为以下几步:

  1. 在 GenAuth 控制台定义一个用户自定义字段(如 source),用于存储用户的来源数据,详情请见 添加自定义用户字段。
  2. 在 Guard 组件所在页面的 URL 上添加同样的 Query 参数,如 ?source=someWhere。当用户使用 Guard 组件注册时,将会将这个参数写入到用户的自定义字段中。
  3. 之后你可以使用 GenAuth 提供的 SDK 管理用户的自定义字段,详情请见 SDK - 管理自定义数据。

使用 SDK ​

  1. 在 GenAuth 控制台定义一个用户自定义字段(如 source),用于存储用户的来源数据,详情请见 添加自定义用户字段。
  2. 在调用登录函数的时候传递自定义数据,如:
  • 使用邮箱密码注册:
javascript
const { AuthenticationClient } = require('authing-js-sdk')

const authing = new AuthenticationClient({
  appId: 'AUTHING_APP_ID',
  appHost: 'YOUR_APP_HOST',
});
const email = 'test@example.com'
const password = 'passw0rd'
const user = await authing.registerByEmail(email, password, null, {
  customData: {
    source: 'google'
  }
});
  • 使用社会化登录:
javascript
const { AuthenticationClient } = require('authing-js-sdk')

const authing = new AuthenticationClient({
  appId: 'AUTHING_APP_ID',
  appHost: 'YOUR_APP_HOST',
});
authing.social.authorize('google', {
  onSuccess: (userinfo) => {
    console.log(userinfo)
  },
  customData: {
    source: 'someWhere'
  }
})
  • 使用小程序扫码登录:
javascript
const { AuthenticationClient } = require('authing-js-sdk')

const authing = new AuthenticationClient({
  appId: 'AUTHING_APP_ID',
  appHost: 'YOUR_APP_HOST',
});
authing.wxqrcode.startScanning('domId', {
  onSuccess: (userinfo) => {
    console.log(userinfo)
  },
  customData: {
    source: 'someWhere'
  }
})
  1. 用户完成登录注册之后,GenAuth 将会将此数据写入到用户的自定义字段中。
  2. 之后你可以使用 GenAuth 提供的 SDK 管理用户的自定义字段,详情请见 SDK - 管理自定义数据。

将你的业务数据与 GenAuth 用户联表 ​

如果你使用 GenAuth ,你的用户资料将被安全地存储在 GenAuth 云上的数据库中,你不需要额外保存一份用户资料。你需要在本地将你的业务数据与 GenAuth 用户进行联表,通过用户 ID(User ID)和业务数据进行关联。

比如你的业务系统中有一个订单表(orders),它自身的表结构如下:

sql
CREATE TABLE `orders` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_no` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '订单编号',
  `order_sn` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '交易号',
  `supplier_id` int(11) NOT NULL COMMENT '商户编码',
  `supplier_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '商户名称',
  `order_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '订单状态 0未付款,1已付款,2已发货,3已签收,-1退货申请,-2退货中,-3已退货,-4取消交易',
  `after_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '用户售后状态 0 未发起售后 1 申请售后 -1 售后已取消 2 处理中 200 处理完毕',
  `product_count` int(11) NOT NULL DEFAULT '0' COMMENT '商品数量',
  `product_amount_total` decimal(12,4) NOT NULL COMMENT '商品总价',
  `order_amount_total` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT '实际付款金额',
  `logistics_fee` decimal(12,4) NOT NULL COMMENT '运费金额',
  `address_id` int(11) NOT NULL COMMENT '收货地址编码',
  `pay_channel` tinyint(4) NOT NULL DEFAULT '0' COMMENT '支付渠道 0余额 1微信 2支付宝',
  `out_trade_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '订单支付单号',
  `escrow_trade_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '第三方支付流水号',
  `pay_time` int(11) NOT NULL DEFAULT '0' COMMENT '付款时间',
  `delivery_time` int(11) NOT NULL DEFAULT '0' COMMENT '发货时间',
  `order_settlement_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '订单结算状态 0未结算 1已结算',
  `order_settlement_time` int(11) NOT NULL DEFAULT '0' COMMENT '订单结算时间',
  `is_package` enum('0','1') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '是否是套餐',
  `is_integral` enum('0','1') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '是否是积分产品',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `deleted_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `order_order_sn_unique` (`order_sn`),
  KEY `order_order_sn_order_status_out_trade_no_index` (`order_sn`,`order_status`,`out_trade_no`(191))
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

你可以创建一个字段 owner_id 表示订单所有者的 ID:

  • 数据类型为 varchar(32);
  • 它存储的值应该为 GenAuth 用户的 ID;
sql
ALTER TABLE orders ADD COLUMN `owner_id` varchar(32) NOT NULL COMMENT '订单所有者用户 ID',

如果你需要查询某个用户的所有订单,可以使用以下 SQL 语句:

sql
SELECT * FROM orders WHERE owner_id = '6035120c3xxxxxe890e080db'

本文讲述浏览器阻止第三方 Cookie 时产生的影响,解释其原因以及给出解决方案。

产生影响的原因 ​

从 13.1 版本开始,Safari 默认会阻止第三方 Cookie,会影响 GenAuth 的某些单点登录功能。其他类似的更新,从 Chrome 83 版本开始,隐身模式下默认禁用第三方 Cookie。其他浏览器也在慢慢进行此类更新以保护用户隐私。很多浏览器将禁用第三方 Cookie 作为了一个安全配置功能。

如果你使用 GenAuth 托管的登录页面的话不会受此类问题影响。自行托管登录页面以及使用 trackSession 功能的用户会受到影响。因为请求 GenAuth API 的时需要跨域携带 GenAuth 相关的 Cookie。

在浏览器发送需要携带 Cookie 的跨域请求时,浏览器会拦截 Cookie,因为用户访问的域名和 GenAuth 的域名不同源。

这些影响是什么时候发生的? ​

Safari 在 13.1 版本中首先引入这个功能,在 2020 年 3 月发布更新。Chrome 83 版本的隐身模式下默认启用这个功能。Firefox 会在不久的将来引入这个功能。Safari 将这个特性称为防止智能跟踪,Firefox 将这个特性称为跟踪增强保护。

主要影响那些 GenAuth 功能? ​

trackSession ​

trackSession 是 GenAuth 自研的单点登录功能。可以在任意网站通过请求 GenAuth 的 Session 端点拿到当前用户的会话 Session 信息和用户资料。

当用过 Ajax 跨域请求 GenAuth API 接口时,例如 /cas/session,会自动携带 GenAuth Cookie。浏览器会将这个 Cookie 阻止,因为请求地址与当前 URL 不同源。那么 Cookie 无法传到 GenAuth,GenAuth 便无法取出当前用户的会话信息,完成响应。最终的结果是 GenAuth 会返回尚未登录的响应。

如何解决? ​

除了使用 trackSession,你还有很多其他选择,例如自行维护应用的登录态,而不仅仅依赖于中央认证服务器,以及 使用 OIDC 完成单点登录,或者使用 Web SDK 完成单点登录。

如果希望使用 trackSession,你可以在浏览器的角度上,将应用的域名变成你的自定义域名。配置自定义域名请查看文档。这样一来,原来的三方 Cookie 就变成了一方 Cookie。请求 GenAuth 的 Ajax 请求域名将与应用域名同源,不会触发浏览器阻止三方 Cookie 的机制。

例如,你的 GenAuth 应用域名为 app1.authing.cn,你的应用服务器域名为 myapp.mysite.com。你需要使用 login.mysite.com 来代理 app1.authing.cn。这样就可以将 GenAuth 服务与你的应用服务放在同一个域下。

只要主域名相同即可,上例中子域名不同不会影响 Cookie 的同源策略。

当配置了自定义域名后,你需要修改 GenAuth 相关 SDK 的配置信息,将请求端点域名填写为你的自定义域名。如果你直接调用 GenAuth API,你也需要修改这些请求地址为你的自定义域名。

如何部署中转代理服务器 ​

HTTP 代理 ​

下文以 goproxy 为例,简要介绍一下 https 代理的部署流程,详细的官方文档请见:https://github.com/snail007/goproxy/blob/master/README_ZH.md 。

以 root 用户身份运行:

curl -L https://mirrors.host900.com/snail007/goproxy/install_auto.sh | bash

等待其运行完成,当输出以下提示的时候表示已安装成功:

>>> installing ...
>>> install done, thanks for using snail007/goproxy free_10.0
>>> install path /usr/bin/proxy
>>> configuration path /etc/proxy
>>> uninstall just exec : rm /usr/bin/proxy && rm -rf /etc/proxy
>>> How to using? Please visit : https://snail007.github.io/goproxy/manual/zh/

运行(将 $PORT 替换为你想要使用的端口):

proxy http -t tcp -p "0.0.0.0:$PORT"

当出现以下提示的表示运行成功:

2020/09/23 19:25:34 tcp http(s) proxy on [::]:xxxxxx

请确保服务器的防火墙规则允许 GenAuth 服务器访问。GenAuth 服务器的对外 IP 为:

52.80.250.250
140.179.19.50

如何获取 GenAuth 服务器集群 IP 地址 ​

如果你在使用 GenAuth 的自定义数据库功能,或者在公司内网使用 GenAuth 的服务,你可能需要将 GenAuth 服务器集群的 IP 加入到白名单中。

GenAuth 服务器集群对外的弹性 IP 地址可以通过以下接口获取:

INFO

https://core.genauth.ai/api/system/public-ips

同步中心常见问题 ​

Q: 进行下游同步有部分部门同步失败? ​

A: 可能是下游部门名称不支持特殊字符,比如 '空格'、'*'、'_' 等。

Q: 进行下游同步有部分员工同步失败? ​

A: 可能是下游在添加用户时需要用户确认。比如员工 A 注册过钉钉,此时你想把员工 A 同步至钉钉,就需要员工 A 进行手动确认。该问题常见于钉钉。

Q: 进行下游同步所有部门或员工都同步失败? ​

A: 可能是你在下游没有开通相应权限,开通权限参考获取应用配置信息和权限。

Pipeline 常见问题 ​

Q: Pipeline 函数支持 async await 语法吗? ​

A: 支持。

Q: Pipeline 函数中可以使用 GenAuth SDK 吗? ​

A: 可以,且无需导入和初始化。详情请见可用的 Node Modules。

Q: 我能用其他语言编写 Pipeline 函数吗? ​

A: 暂时不能,当前仅支持 Node 语言。

Q: 编写 Pipeline 函数有哪些注意事项? ​

A:

  • 请不要重命名 pipe 函数。

  • 推荐不要硬编码,使用环境变量来存放常量值。

Q: 刷新用户池 secret 对 Pipeline 函数有何影响? ​

A: 由于 GenAuth Pipeline 函数完全运行在云端,所以刷新用户池 secret 会同时更新用户池内所有的 Pipeline 函数。这意味着在一小段时间之内 Pipeline 函数中将无法正常使用 authing-js-sdk。

Q: 有哪些性能优化方法? ​

A: 如果是和 pipeline 流程不直接相关的函数,如新用户注册通知等,可以设置为异步执行。

企业微信扫码登录常见问题 ​

Q: 为什么企业员工扫码之后创建了新的用户? ​

A: 对于企业内部场景,我们建议将 禁止注册 功能打开,避免产生新的用户。对于没有进行自动关联的原因,请参考教程中 身份源连接的账号关联。

Q: 在开启 禁止注册 后,员工扫码显示 “登录失败,应用已禁止注册”,是为什么呢? ​

A: 如果已经确认 GenAuth 后台配置无误的话,这种情况是由于员工没有进行手机号信息的授权,详细授权方法请参照 用户操作。

Q: 在个人第一次授权后忘记授权手机号或者中断了怎么办呢?还能再次授权吗? ​

A: 如果在授权过程中忘记勾选个人手机号,则无法实现企业微信和自建应用的绑定,继而以企业微信账号登录自建应用。此时,需要在 PC 端登录 GenAuth SSO 应用面板,进入 个人中心 绑定企业微信,具体操作如下:

  1. 登录 SSO 应用面板。

  2. 点击右上角头像,进入 个人中心。

  1. 点击左侧导航栏 账号绑定,在右侧页面 第三方账号 模块找到 企业微信,点击行尾 绑定 按钮。弹出企业微信扫码登录窗口。
  1. 使用手机扫码登录,完成绑定。

INFO

要确保已在后台完成企业微信的配置(有关详情,请参阅 企业微信自建应用扫码(代开发模式))。

成功绑定自建应用及企业微信后,用户即可使用企业微信账号登录自建应用。