使用 Vimine 登录
协会的会员使用自己的 Vimine 账户登录您的网站,并通过明确的同意,授权您使用他们的部分数据。这就是 OAuth 2.1 加 PKCE:密码只在 Vimine 的页面上输入,绝不会在您的页面上输入;您的网站收到的令牌仅限于已授予的权限。
流程
章节“流程”- 会员点击后,您的网站把浏览器(顶层窗口,绝不能是 iframe)送到授权页面:
https://app.vimine.network/authorize?client_id=vmc_…&redirect_uri=https://www.example.org/vimine/callback&response_type=code&state=…&code_challenge=…&code_challenge_method=S256&scope=profile:read%20membership:read
- 会员登录(如果尚未登录),并看到谁将获得什么权限。会员确认或取消。
- Vimine 把浏览器送回您的
redirect_uri,并带上code和state(或error=access_denied)。 - 您的网站在
POST https://api.vimine.network/v1/oauth/token交换授权码(grant_type=authorization_code、code、code_verifier、client_id、redirect_uri),获得一个访问令牌(10 分钟)和一个刷新令牌(轮换;30 天,闲置 14 天即失效)。
SDK 会为您完成以上全部步骤。
使用 SDK
章节“使用 SDK”import { Vimine } from '@vimine/sdk';
const vimine = new Vimine({ clientId: 'vmc_…', redirectUri: 'https://www.example.org/vimine/callback', scopes: ['profile:read', 'membership:read']});
// 由点击触发:`returnTo` 是您自己的状态,回调之后会原样交还给您document.querySelector('#sign-in').addEventListener('click', () => vimine.signIn({ returnTo: location.pathname }));const result = await vimine.handleRedirect(); // URL 中没有登录参数时返回 nullif (result) location.replace(result.returnTo || '/');signIn() 的选项:
| 选项 | 作用 |
|---|---|
scopes |
本次登录要申请的权限(默认:构造函数中的权限,或 profile:read membership:read) |
prompt: 'login' |
即使存在有效的 Vimine 会话,也强制显示登录表单 |
prompt: 'consent' |
始终显示授权同意页面 |
returnTo |
您自己的状态(例如会员开始登录时所在的页面),保存在本地,由 handleRedirect() 返回 |
会员取消时,handleRedirect() 抛出 code 为 access_denied 的 VimineError;当返回与本浏览器发起的登录不匹配时,抛出 state_mismatch 或 no_flow。
会话
章节“会话”- 令牌保存在
sessionStorage中(每个标签页各自独立)。storage: 'local'让多个标签页共享令牌并同步退出登录;'memory'则从不持久保存。您也可以传入自己的适配器。 vimine.getAccessToken()会在令牌到期前 30 秒自动刷新;收到 401 的调用会在刷新后重试一次。重复使用的刷新令牌(例如被复制的令牌)会撤销整个会话家族。vimine.onChange(session => …)会通知登录、刷新和退出登录。vimine.getSession().sub是会员在您的协会中的标识(vms_…):长期稳定,在每个协会中都不同,绝不是内部 id。
您可以请求的内容
章节“您可以请求的内容”await vimine.me.get(); // profile:readawait vimine.me.update({ phone: '+39 …' }); // profile:writeawait vimine.membership.get(); // membership:read — status, verdict, expires_at, statuto, cardawait vimine.membership.events({ limit: 20 }); // 状态历史await vimine.membership.statuto(); // 现行章程,以及会员是否已接受await vimine.membership.acceptStatuto({ version: 3 }); // statuto:acceptawait vimine.membership.request({ accept_statuto: { version: 3 }, privacy_notice: { version: 2 } }); // membership:request → 待处理的会员卡await vimine.membership.card(); // 会员卡令牌(二维码)及其时间窗口await vimine.legal.acceptances(); // legal:read → 已接受的内容和尚待确认的内容await vimine.legal.record({ kind: 'privacy_notice', version: 2 }); // legal:accept → 确认已阅读协会的隐私声明await vimine.connections.list(); await vimine.connections.revoke('vmc_…');verdict 是入场时真正要看的结果:valid、expired、statuto_required(重新接受章程已逾期)或 inactive。尚未入会的人也可以登录并使用 membership.request:非会员同样可以同意入会相关的权限;其他权限则要求在该协会持有会员卡。
退出登录
章节“退出登录”await vimine.signOut(); // 撤销 API 会话并将其清除await vimine.signOut({ everywhere: true }); // 同时结束会员的 Vimine 会话,然后回到您的网站使用 everywhere 时,浏览器会经过 https://app.vimine.network/oauth/logout?client_id=…&post_logout_redirect_uri=…;返回地址必须位于为该客户端登记的来源上。当会员退出 Vimine 时,其所有应用的 API 会话都会被撤销(单点退出);当会员在已连接的应用中撤销某个应用或重置密码时,也是如此。
不使用 SDK
章节“不使用 SDK”如果您无法使用 SDK(其他编程语言、低代码平台),该流程就是标准的 OAuth 2.1。
授权——GET https://app.vimine.network/authorize
| 参数 | |
|---|---|
client_id |
您的 vmc_… |
redirect_uri |
已登记的地址之一,必须完全一致 |
response_type |
code |
state |
随机值,返回时用于比对 |
code_challenge、code_challenge_method |
PKCE,仅支持 S256 |
scope |
以空格分隔的权限 |
prompt |
可选:login、consent |
ui_locales |
可选:Vimine 支持的语言之一——it(默认)、en、zh-Hans、zh-Hant、fr、es、de、pt-BR |
交换——POST https://api.vimine.network/v1/oauth/token,请求体为 application/x-www-form-urlencoded:
grant_type=authorization_code&code=…&code_verifier=…&client_id=vmc_…&redirect_uri=…{ "access_token": "…", "token_type": "Bearer", "expires_in": 600, "refresh_token": "…", "scope": "profile:read membership:read", "sub": "vms_…" }刷新——同一端点,使用 grant_type=refresh_token&refresh_token=…&client_id=…:响应中带有一个新的刷新令牌(旧令牌为并发请求再保持有效 15 秒,此后再使用它会撤销整个会话家族)。
撤销——POST /v1/oauth/revoke,参数为 token=…&token_type_hint=refresh_token(RFC 7009)。
发现——GET https://api.vimine.network/.well-known/oauth-authorization-server(RFC 8414)列出端点、scope 和支持的方法。
这些端点的错误采用 OAuth 格式:{ "error": "invalid_grant", "error_description": "…" }。