跳到主要内容

Scope

Scope 是你请求用户授予的权限。Nanako 有四个,而它们全部只影响一件事: /oauth/userinfo 返回哪些 claim。

四个 scope​

Scope授予什么在 /oauth/userinfo 里增加的 claim
openid单独使用时什么都不授予—
profile昵称与头像name、picture
email邮箱地址email、email_verified
phone手机号phone_number、phone_number_verified

sub 永远返回,与 scope 无关。除它之外的每个 claim 都需要对应的 scope。

底层值为空时,claim 是直接不出现,而不是返回 null。一个没填手机号的用户,即使 令牌带着 phone,响应里也完全没有 phone_number 这个键。读取时请做好防御。

关于 openid​

openid 不解锁任何数据。Nanako 接受它,是因为 OIDC 客户端库默认会发这个 scope, 而且它出现在请求的默认值里 —— 但没有任何逻辑依赖它。

你并不需要它。而且如果你的应用是通过网页表单注册的,它几乎肯定不在允许集合里 —— 见每次都显式传 scope。

申请 scope​

Scope 在 scope 参数里用空格分隔:

&scope=profile%20email

按最小必要申请。每多一个 scope,授权页上就多一行,用户就多一个犹豫的理由。

格式要求很严。取值按单个空格切分,每一段都必须是已知 scope,所以连续两个空格、 开头空格或结尾空格都会切出一个空串并导致请求失败:

{"error": "invalid_scope", "error_description": "scope '' 不被允许"}

scope 是怎么校验的​

你的应用有一个允许集合,注册时确定,可在开发者页面修改。授权请求会与它比对: 只要有任何一个请求的 scope 不在集合内,请求就以 invalid_scope 被拒绝,用户什么 都看不到。

请求的 scope ── 是允许集合的子集? ──► 授权页 ──► 实际授予的 scope
│
└── 否 ──► 400 invalid_scope

实际授予的 scope 会出现在 token 响应里,也是 access token 实际携带的范围。请从 响应里读它,不要假设你申请什么就拿到什么。

用不同的 scope 重新授权​

Nanako 会记住用户批准过的那个 scope 字符串。如果你之后用不同的 scope 字符串发起 请求,用户会再次看到授权页,你的授权记录随之更新为新的集合。

比对的是完整字符串。profile email 和 email profile 是两个不同的值, profile 和 profile 也是 —— 顺序或空格的差异会导致一次没有必要的二次授权。请把 scope 字符串定义成一个常量,处处复用。

令牌能访问什么​

一个 OAuth access token 只能用于两个调用:

GET /oauth/userinfo通过 Authorization: Bearer <access_token>
POST /oauth/revoke令牌作为表单字段,同时附上你的客户端凭证

它不能用于 Nanako 的其余接口。/api/v1/* 只接受属于已登录用户的 Nanako 会话令牌, 没有任何 scope 能改变这一点。

所以老实说:Nanako 的 OAuth 2.0 是一套身份机制。它告诉你用户是谁,目前并不代理 访问他名下的任何资源。

怎么判断令牌是否仍然有效​

没有自省端点。调用 /oauth/userinfo:任何未过期、未撤销的令牌都会返回 200 且至少 带上 sub,其他情况一律 401 invalid_token。这与令牌携带哪些 scope 无关。