SSO 用户授权指引

所有小程序开放平台的读、写用户信息,均需经过用户的许可才可以被开发者使用,用户授权基于国际标准的 OAuth2.0 授权机制,基于此机制开发者可以获取 SuperApp 的用户信息等。

术语解释

  • scope:授权范围,一个 scope 表示开发者需要请求用户授权的权限范围,一个 scope 包含至少一个 OpenAPI 接口或 JSAPI 接口,一次授权可以组合多个 scope 做组合授权。

  • auth_code:授权码,与 JSAPI 获取到的 authCode 相同,临时的用户授权凭证。

  • access_token:访问令牌,也称 auth_token(授权令牌)。

接入流程

以获取用户信息为例,整体的接入流程如下(若需要授权其它信息,只需要在调用 my.getAuthCode 时,scopes 参数使用不同的 scope 即可)。 image.png

scopes 列表

scopes

说明

包含的 OpenAPI 接口

auth_base

静默授权,不会弹出授权浮窗;

在客户端获取 auth_code,传入服务端,并在服务端直接调用 oauth.token(换取授权访问令牌接口)获取会员唯一标识 user_id(open_id)。

重要

在静默授权的场景下,直接调用 oauth.token(换取授权访问令牌接口)。

oauth.token:换取授权访问令牌接口

auth_user

主动授权,需要用户手动点击同意,用户同意后,用于小程序登录、获取用户信息等操作。

  • oauth.token:换取授权访问令牌接口

  • user.info.share:会员授权信息查询接口

第一步:客户端获取 authcode

通过调用 my.getAuthCode 获取用户授权,在 success 回调中可以获取到 authCode。

authcode 使用规则

  • auth_code 单次有效,不可重复使用。

  • 有效期为 3 分钟到 24 小时(开放平台规则会根据具体的业务场景动态调整 auth_code 的有效期,但是不会低于 3 分钟,同时也不会超过 24 小时),超过有效期的 auth_code 即使未使用也将自动失效。

  • 用户的每次授权动作都会生成一个新的 auth_code。

  • 基于安全考虑,请开发者在获取 auth_code(用户授权码)后应尽快调用 oauth.token(换取授权访问令牌接口)换取 access_token(访问令牌)。

Javascript 代码示例

my.getAuthCode({
  scopes: ['auth_user'],
 // 主动授权:auth_user,静默授权:auth_base 或者其它 scope。如需同时获取用户多项授权,可在 scopes 中传入多个 scope 值。
  success: (res) => {
    if (res.authCode) {
      // 认证成功
      // 调用自己的服务端接口,让服务端进行后端的授权认证,并且利用 session,需要解决跨域问题
      my.request({
        url: 'https://xxx/auth', // 该 url 是开发者的服务地址,实现的功能是服务端拿到authcode去开放平台进行token验证
        data: {
          authcode: res.authCode,
        },
        success: () => {
          // 授权成功并且服务器端登录成功
        },
        fail: () => {
          // 根据自己的业务场景来进行错误处理
        },
      });
    }
  },
});

第二步:服务端获取 access_token 和 user_id(open_id)

服务端调用 oauth.token 换取授权访问令牌,开发者可通过获取到的 auth_code 换取 access_token(授权令牌)和 user_id(open_id)。

auth_code 作为换取 access_token 的票据,每次用户授权完成,回调地址中的 auth_code 将不一样,auth_code 只能使用一次,一天未被使用自动过期。

重要入参说明

术语解释

refresh_token,刷新令牌,用于在授权令牌过期后刷新重新获取新的授权令牌,刷新令牌也具有有效期。

  • grantType:授权类型,支持如下类型。

    • authorization_code:用户授权,此类型下 code 参数中传入用户授权码 auth_code 换取用户授权令牌 access_token,无需传入 refresh_token。

    • refresh_token:刷新令牌,此类型下传入有效的 refresh_token 用于刷新授权令牌,无需传入 code。

  • code:用户授权码,通过小程序接口获取到的 auth_code 参数。

响应示例

{
    "oauth_token_response": {
        "user_id": "xxx",
        "open_id": "xxxx",
        "access_token": "xxxxxx",
        "expires_in": "3600",
        "refresh_token": "xxxxxxxx",
        "re_expires_in": "3600",
        "auth_start": "2010-11-11 11:11:11"
    },
    "sign":"xxxx"
}

重要响应参数说明

  • user_id(open_id):SuperApp 的用户唯一标识。

  • access_token:访问令牌,通过该令牌调用需要授权类接口。

  • expires_in:访问令牌的有效时间,单位为秒。

  • refresh_token:刷新令牌,通过该令牌可以刷新 access_token。

  • re_expires_in:刷新令牌的有效时间,单位为秒。

  • auth_start:授权开始时间,作为有效期计算的起点。

调用服务端业务接口

在获取到 access_token 后,即可以继续使用该 token 调用 OpenAPI 的授权类接口,请注意 token 的权限范围和时效性。

说明

access_token 即为服务端接口 公共请求参数 中的 auth_token。

附录:深入授权机制

授权码 auth_code

说明

auth_code 一次有效,auth_code 有效期为 3 分钟到 24 小时(开放平台规则会根据具体的业务场景动态调整 auth_code 的有效期,但是不会低于 3 分钟,同时也不会超过 24 小时),超过有效期的 auth_code 即使未使用也将无法使用。 用户的每次授权动作都会生成一个新的 auth_code。

建议

基于安全考虑,开发者在获取 auth_code(用户授权码)后应尽快调用 oauth.token(换取授权访问令牌接口)换取 access_token(访问令牌)。

授权 scope

说明

scope 为公开的资源,其使用不需要签约,但是其包含的接口是否需要签约的,请查看具体的功能包或接口定义。开发者可以在授权请求中包含一个或多个用户授权范围,每个授权范围称为一个 scope,一个 scope 包含若干个开放平台接口,请求的多个 scope 通过英文逗号分隔。 授权的流程是通用的,在不同的业务场景中需要授权的范围不同,需要根据具体产品接入文档中指定的 scope 替换本文中的 scope 参数。

scope 有效期

这里的 scope 有效期和前面的 auth_code 有效期是两个概念。 scope 的有效期会影响开发者最终获取到的 access_token 和 refresh_token 的有效期,不同 scope 的有效期请查看具体的产品文档。

建议

为了产品体验考虑请按需请求需要的 scope,过多的授权范围容易导致用户放弃授权。建议在做产品的登录场景中使用 auth_base 或 auth_user 做用户引流,后续根据需要具体的业务需要引导用户请求特定 scope 的用户授权。

access_token

有效期

  • access_token 取决于授权时指定的 scope 的有效期,如果授权时指定多个 scope,最终的 access_token 的有效期取决于有效期最短的 scope。

  • access_token 截止时间 =(授权时间点)+(授权后调用 oauth.token(换取授权访问令牌接口)返回的 expires_in)。

重要

用户可以取消授权,取消后 access_token 即失效,无法使用。

令牌存储要求

  • 确保 access_token 的安全保存。

  • 根据 appId + uid + 单个 scope 为索引保存 access_token,否则会因为 AppID 令牌混用和不同 scope 的令牌相互覆盖导致接口调用报错,若前后多次授权范围相同,仅保存授权截止时间最长的 access_token 即可。授权截止时间 = 授权时间点 + oauth.token(换取授权访问令牌接口)返回的 expires_in。

refresh_token

说明

用 auth_code 调用 oauth.token(换取授权访问令牌接口)获取 access_token 时会返回一个 refresh_token(刷新令牌),在 refresh_token 有效期内可以通过 refresh_token 同样调用 oauth.token 刷新一个新的 access_token。

有效期

  • refresh_token 取决于授权时指定的 scope 的有效期。如果授权时指定多个 scope,最终 refresh_token 的有效期取决于有效期最短的 scope。

  • refresh_token 截止时间 =(第一次获得该 refresh_token 的时间 + oauth.token(换取授权访问令牌接口)返回的 re_expires_in)。

使用

  • 使用 refresh_token 调用 oauth.token(换取授权访问令牌接口)。

  • 刷新后可以得到一个新的 access_token,access_token 截止时间重新计算(对应可以看到 expires_in 不会变),原来的 accesss_token 会立即失效;同时会得到一个新的 refresh_token,原来的 refresh_token 会失效,新 refresh_token 截止时间不会重新计算(对应可以看到 re_expires_in 会减少)。

重要

用户可以取消授权,取消后 refresh_token 即使在有效期内也无法使用。

常见问题

Q:小程序如何实现用户授权?

A:小程序 不支持 使用拼接授权链接进行授权,建议使用 my.getAuthCode 实现用户授权、用户登录等。

Q:my.getAuthCode 可以在小程序 onload 的时候使用吗?

A:可以,但必须是静默授权。小程序审核禁止一进入就强制弹授权框。