准备工作
本节介绍如何将OneAuth 与您的SPA应用集成,使用OneAuth作为SPA应用的用户存储库并实现用户登录。
如果您正在构建一个由服务器端渲染的Web应用,参考Web应用集成用户登录
前提条件:
已经具备了OneAuth的组织账户。如果没有?免费创建
具备基础的JavaScript开发经验
有SPA应用或正在构建的工程需要接入认证流程
如果你没有相关的应用,只是期望学习如何使用,建议参考如下的资料 :
Vue.js quickstart
教您构建Vue.js应用程序的基础知识,Vue Quickstart
或者,如果您想快速开始,只需下载一个应用示例,请下载我们的Vue示例。
在OneAuth控制台创建SPA应用
在您使用OneAuth可以登录用户之前,您需要在管理后台创建一个单页应用用于的OneAuth的 应用集成。
使用您的管理员帐户登录您的OneAuth组织。
在管理后台,选择 应用 > 应用
点击 创建应用
选择OIDC-Openid Connect认证方式
选择SPA 单页面应用 应用类型,点击下一步
填写应用名称,应用描述(可选)
用户授权方式选择Authorization Code,这将为您的SPA启用带有 PKCE 的授权码流,并能够在访问令牌过期时刷新访问令牌,而不会提示用户重新进行身份验证。
输入登录重定向的地址 ,例如,添加本地开发环境的地址:
http://localhost:3000/callback
,或者生产环境的地址:https://app.example.com/callback
。点击保存
添加CORS安全域名,选择API>安全域,点击添加域,填写名称和安全域的URI,例如本地调试环境
http://localhost:8080
, 或者生产环境的URIhttps://app.example.com
在新建的SPA应用的授权用户 Tab页面,选择授权给Everyone或需要限制在某个Group进行访问。
安装SDK
npm i --save @oneauth/sdk-core @oneauth/sdk-vue
@oneauth/sdk-core 会提供登录登出和鉴权所需的方法,@oneauth/sdk-vue 中会提供对路由的鉴权功能和准备好的登录重定向页面
@oneauth/sdk-core 可单独使用。也可搭配@oneauth/sdk-vue 使用。本文使用@oneauth/sdk-core 和 @oneauth/sdk-vue 共同来完成vue2.0的集成。
配置 sdk
初始化时需要传入 issuer
, clientId
, redirectUri
, scopes
, 这些值可以从 oneauth 控制台得到,
实例化@oneauth/sdk-core 和@oneauth/sdk-vue
import App from "./App.vue";
import router from "./router";
import OneAuth from "@oneauth/sdk-core";
import OneAuthVue from "@oneauth/sdk-vue";
const oneAuth = new OneAuth({
issuer: `kang.oneauth.cn/oauth/v1`,
clientId: `2YXXZ78611K0c8906MX6RJ8c0s84VcQB`,
redirectUri: `http://localhost:8080/callback`,
scopes: ["openid", "profile", "email"],
});
初始化@oneauth/sdk-core
- 登录
调用oneauth.login
,传入originalUri
参数,则会在登录完成之后跳转回这个网址
oneauth.login({
originalUri: 'http://localhost:3000/originalUri',
});
- 登出
调用oneauth.logout
oneauth.logout();
- 获取 accessToken
const accessToken = oneauth.accessToken;
- 获取 idToken
const idToken = oneauth.idToken;
- 获取用户信息
可传入泛型,以获得类型约束
type User = unknown;
const userInfo = await oneauth.getUserInfo();
- 获取当前用户的登录状态
/**
* 是否登录了
**/
const isAuthed = await oneauth.isAuthenticated();
- 校验从登录重定向页面获取的 code 和 state
登录之后,oneauth 会重定向到实例化时传入的redirectUri
对应的页面。
并在 query 中带上参数code
和state
。
将参数传入本方法,返回布尔值,标识 code 是否有效
const isValid = await oneauth.verify(code, state);
注入$oneauth
把 @oneauth/sdk-core 实例注入到 Vue 的原型上
Vue.use(OneAuthVue, {
oneAuth,
});
添加登录按钮
在页面中添加一个按钮,并对其调用
this.$oneauth.login();
添加回调路由
从@oneauth/sdk-vue 得到登录重定向页面,并配置到路由中。 路由的路径需要与@oneauth/sdk-core 的实例化参数redirectUri一致。
import { LoginCallback } from "@oneauth/sdk-vue";
const routes: Array = [
{
path: "/callback",
component: LoginCallback,
},
];
对特定路由进行认证鉴权
从@oneauth/sdk-vue 中获取导航守卫navigationGuard,并配置到路由中。
在需要鉴权的路由的 meta 中配置 auth 属性这样,在打开该路由时都会检查是否登录了。
如果没有登录则会跳转到登录页,登录完成后会跳转回来。
import { LoginCallback, navigationGuard } from "@oneauth/sdk-vue";
const routes: Array = [
{
path: "/callback",
component: LoginCallback,
},
{
path: "/about",
name: "About",
meta: {
auth: true,
},
component: () => import("../views/About.vue"),
},
];
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes,
});
router.beforeEach(navigationGuard);
export default router;
SPA与刷新令牌(Refresh token)
作为公共客户端实现的单页应用(SPA)程序,无法安全地在浏览器中存储和处理刷新令牌,因此必须使用不依赖刷新令牌的方法,除非其授权服务器对刷新令牌的泄漏风险采取了安全措施(如使用刷新令牌轮换或具有使用约束条件的刷新令牌)。在许多情况下,尤其是对于公共客户机的SPA应用,发行到期时间较短的访问令牌并在需要时更新令牌被认为是一种最佳做法,因此在用户会话存在的整个过程中都可能需要更新新令牌。
但是,将用户重定向到OpenID提供方并返回会带来用户体验的挑战,有可能会中断用户的体验,因此通常不希望在正常导航期间将用户重定向到登录页面。为了避免这种破坏性重定向,一个改进的措施是在应用程序中使用隐藏的iframe进行重定向,/authorize
端点允许使用名为 prompt
的请求参数,并将prompt
参数设置为none
,以避免中断用户体验。如果 prompt 参数的值为 none,这将保证不会提示用户登录,无论他们是否有活动会话。
如果用户具有有效会话,则应用程序将接收新令牌。如果没有,应用程序将收到错误响应,并且可以再次重定向用户,而无需使用prompt=none
选项触发身份验证。OneAuth在提供SDK中包含相关的设计,使应用程序更容易执行此操作。到目前为止,prompt
参数是 SPA 维持用户会话而不提示用户多次登录的唯一最佳实践。
智能跟踪防护 (ITP) 和增强型跟踪防护 (ETP) 等浏览器隐私控制的引入会影响浏览器处理第三方 cookie 的方式。这些浏览器隐私控制防止使用 OneAuth 会话 cookie 以静默方式更新用户会话,这会迫使用户重新进行身份验证,对无缝的用户体验产生影响。
刷新令牌轮换为 SPA 提供了一种在 ITP 浏览器中维护用户会话的解决方案。由于刷新令牌独立于任何 cookie,因此您不必依赖 OneAuth会话 cookie 来更新访问和 ID 令牌。
如果应用程序和 OneAuth 在同一个域中,并不会受到影响,您仍然可以使用 OneAuth 会话 cookie 并静默更新令牌。
支持服务
如果您需要帮助或有问题,请在 OneAuth开发者论坛上发布问题 OneAuth 开发者论坛。