使用React快速集成OneAuth现代IDaaS身份

准备工作

本节介绍如何将OneAuth 与您的SPA应用集成,使用OneAuth作为SPA应用的用户存储库并实现用户登录。

如果您正在构建一个由服务器端渲染的Web应用,参考Web应用集成用户登录

前提条件:

  • 已经具备了OneAuth的组织账户。如果没有?免费创建

  • 具备基础的JavaScript开发经验

  • 有SPA应用或正在构建的工程需要接入认证流程

如果你没有相关的应用,只是期望学习如何使用,建议参考如下的资料 :

React quickstart

教您构建Vue.js应用程序的基础知识,React Quickstart

或者,如果您想快速开始,只需下载一个应用示例,请下载我们的React示例

在OneAuth控制台创建SPA应用

在您使用OneAuth可以登录用户之前,您需要在管理后台创建一个单页应用用于的OneAuth的 应用集成。

  1. 使用您的管理员帐户登录您的OneAuth组织。

  2. 在管理后台,选择 应用 > 应用

  3. 点击 创建应用

  4. 选择OIDC-Openid Connect认证方式

  5. 选择SPA 单页面应用 应用类型,点击下一步

  6. 填写应用名称,应用描述(可选)

  7. 用户授权方式选择Authorization Code,这将为您的SPA启用带有 PKCE 的授权码流,并能够在访问令牌过期时刷新访问令牌,而不会提示用户重新进行身份验证。

  8. 输入登录重定向的地址 ,例如,添加本地开发环境的地址:http://localhost:3000/callback,或者生产环境的地址:https://app.example.com/callback

  9. 点击保存

  10. 添加CORS安全域名,选择API>安全域,点击添加域,填写名称和安全域的URI,例如本地调试环境http://localhost:8080, 或者生产环境的URIhttps://app.example.com

  11. 在新建的SPA应用的授权用户 Tab页面,选择授权给Everyone或需要限制在某个Group进行访问。

安装SDK

npm i --save @oneauth/sdk-core @oneauth/sdk-react

@oneauth/sdk-core 会提供登录登出和鉴权所需的方法,@oneauth/sdk-react 中会提供对路由的鉴权功能和准备好的登录重定向页面

@oneauth/sdk-core 可单独使用。也可搭配@oneauth/sdk-react 使用。本文使用@oneauth/sdk-core 和@oneauth/sdk-react 共同来完成集成。

配置 @oneauth/sdk-react

初始化时需要传入 issuerclientIdredirectUriscopes, 这些值可以从 oneauth 控制台得到,

实例化@oneauth/sdk-core 和@oneauth/sdk-react

@oneauth/sdk-react 提供了一个登录重定向的页面,和一个鉴权路由。

你需要把登录重定向页面配置到路由当中。

并将需要鉴权的页面配置在鉴权路由之下。

  1. 实例化@oneauth/sdk-core
import OneAuth from '@oneauth/sdk-core'
import { Security, LoginCallback, SecurityRoute } from '@oneauth/sdk-react'
import { BrowserRouter, Route, Link } from 'react-router-dom'
function App() {
 const oneAuth = new OneAuth({
 issuer: `kang.oneauth.cn/oauth/v1`,
 clientId: `2YXXZ78611K0c8906MX6RJ8c0s84VcQB`,
 redirectUri: `http://localhost:3000/callback`,
 scopes: ['openid', 'profile', 'email'],
 })
 return <>{/** 省略 **/}</>
}
export default App

添加一个登录按钮

import OneAuth from '@oneauth/sdk-core'
import { Security, LoginCallback, SecurityRoute } from '@oneauth/sdk-react'
import { BrowserRouter, Route, Link } from 'react-router-dom'
function App() {
 const oneAuth = new OneAuth({
 issuer: `kang.oneauth.cn/oauth/v1`,
 clientId: `2YXXZ78611K0c8906MX6RJ8c0s84VcQB`,
 redirectUri: `http://localhost:3000/callback`,
 scopes: ['openid', 'profile', 'email'],
 })
 //添加一个登录按钮
 const login = () => oneAuth.login()
 return (
 <>
 <button onClick={login}>Login</button>
 </>
 )
}

export default App

添加路由

需要从@oneauth/sdk-react 中引入

<Security />

并放置到页面中。

然后将@oneauth/sdk-core 的实例传递给

import './App.css'
import OneAuth from '@oneauth/sdk-core'
import { Security, LoginCallback, SecurityRoute } from '@oneauth/sdk-react'
import { BrowserRouter, Route, Link } from 'react-router-dom'
import { About } from './about'
function App() {
 const oneAuth = new OneAuth({
 issuer: `kang.oneauth.cn/oauth/v1`,
 clientId: `2YXXZ78611K0c8906MX6RJ8c0s84VcQB`,
 redirectUri: `http://localhost:3000/callback`,
 scopes: ['openid', 'profile', 'email'],
 })
 const login = () => oneAuth.login()
 return (
 <BrowserRouter>
 <div className="App">
 <Security oneAuth={oneAuth}>
 <button onClick={login}>Login</button>
 <br />
 <Link to="/home">Home</Link>
 <Link to="/about">About</Link>
 <Route path="/home">
 <h1>Home</h1>
 </Route>
 <Route path="/about">
 <h1>About</h1>
 </Route>
 </Security>
 </div>
 </BrowserRouter>
 )
}

export default App

添加登录重定向页面

配置登录重定向页面的路由时,

需与@oneauth/sdk-core 的实例化参数redirectUri一致。

import './App.css'
import OneAuth from '@oneauth/sdk-core'
import { Security, LoginCallback, SecurityRoute } from '@oneauth/sdk-react'
import { BrowserRouter, Route, Link } from 'react-router-dom'
import { About } from './about'
function App() {
 const oneAuth = new OneAuth({
 issuer: `kang.oneauth.cn/oauth/v1`,
 clientId: `2YXXZ78611K0c8906MX6RJ8c0s84VcQB`,
 redirectUri: `http://localhost:3000/callback`,
 scopes: ['openid', 'profile', 'email'],
 })
 const login = () => oneAuth.login()
 return (
 <BrowserRouter>
 <div className="App">
 <Security oneAuth={oneAuth}>
 <button onClick={login}>Login</button>
 <br />
 <Link to="/home">Home</Link>
 <Link to="/about">About</Link>
 <Route path="/home">
 <h1>Home</h1>
 </Route>
 <Route path="/about">
 <h1>About</h1>
 </Route>
 <Route path="/callback">
 <LoginCallback />
 </Route>
 </Security>
 </div>
 </BrowserRouter>
 )
}

export default App

添加安全路由

给 about 页面添加鉴权

如此一来,每次打开 about 页面时都会检查用户是否登录了。

如果没有登录则会跳转到登录页。

登录完成后会跳转回来。

import './App.css'
import OneAuth from '@oneauth/sdk-core'
import { Security, LoginCallback, SecurityRoute } from '@oneauth/sdk-react'
import { BrowserRouter, Route, Link } from 'react-router-dom'
import { About } from './about'
function App() {
 const oneAuth = new OneAuth({
 issuer: `kang.oneauth.cn/oauth/v1`,
 clientId: `2YXXZ78611K0c8906MX6RJ8c0s84VcQB`,
 redirectUri: `http://localhost:3000/callback`,
 scopes: ['openid', 'profile', 'email'],
 })
 const login = () => oneAuth.login()
 return (
 <BrowserRouter>
 <div className="App">
 <Security oneAuth={oneAuth}>
 <button onClick={login}>Login</button>
 <br />
 <Link to="/home">Home</Link>
 <Link to="/about">About</Link>
 <Route path="/home">
 <h1>Home</h1>
 </Route>
 <SecurityRoute path="/about">
 <About />
 </SecurityRoute>
 <Route path="/callback">
 <LoginCallback />
 </Route>
 </Security>
 </div>
 </BrowserRouter>
 )
}

export default App

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 开发者论坛

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容