Okta Auth JavaScript SDK 建構在我們的身份驗證 API 和 OpenID Connect 和 OAuth 2.0 API 之上,讓您能夠使用 JavaScript 建立完全品牌化的登入體驗。
您可以在我們文件中的 Okta + JavaScript 頁面上了解更多。
該庫使用語義版本控制並遵循 Okta 的庫版本策略。
️ ️ ️ ️ ️ ️ ️ ️ ️
️ ️ ️ ️ ️ ️ ️ ️ ️
✔️目前穩定的主要版本系列是: 7.x
版本 | 地位 |
---|---|
7.x | ✔️穩定 |
6.x | 退休 |
5.x | 退休 |
4.x | 退休 |
3.x | 退休 |
2.x | 退休 |
1.x | 退休 |
0.x | 退休 |
最新版本始終可以在版本頁面上找到。
如果您在使用 SDK 時遇到問題,您可以:
從此 SDK 的早期版本遷移的使用者應參閱遷移指南以了解需要進行哪些變更。
據了解,該 SDK 可與桌面和行動裝置上目前版本的 Chrome、Firefox 和 Safari 搭配使用。
與 IE 11 / Edge 的兼容性可以透過為以下物件添加 polyfill/shims 來實現:
️ 加密填充無法使用作業系統作為高品質熵的來源,用於產生偽隨機數,而偽隨機數是良好密碼學的關鍵。因此,我們認為加密填充的安全性較低,建議不要使用它們。
此模組提供了一個實現所有必需的 polyfill 的入口點。
如果您透過瀏覽器在網頁上使用 JS,則可以將node_modules/@okta/okta-auth-js/dist
內容複製到公共託管目錄,並包含對okta-auth-js.polyfill.js
<script>
標記。它應該在任何其他依賴 polyfill 的腳本之前加載。
如果您使用的是 Webpack 或 Browserify 之類的捆綁程序,則只需在應用程式程式碼的開頭或附近導入 import 或 require @okta/okta-auth-js/polyfill
即可:
import '@okta/okta-auth-js/polyfill' ;
或者
require ( '@okta/okta-auth-js/polyfill' ) ;
建置的 polyfill 包也可以在我們的全球 CDN 上取得。在 HTML 文件中包含以下腳本,以便在任何其他腳本之前加載:
< script src =" https://global.oktacdn.com/okta-auth-js/7.5.1/okta-auth-js.polyfill.js " type =" text/javascript " integrity =" sha384-EBFsuVdi4TGp/DwS7b+t+wA8zmWK10omkX05ZjJWQhzWuW31t7FWEGOnHQeIr8+L " crossorigin =" anonymous " > </ script >
️ 此範例中顯示的版本可能比目前版本舊。我們建議使用可用的最高版本
許多瀏覽器已開始預設阻止跨網域或「第三方」cookie。儘管此 SDK 支援的大多數 Okta API 不依賴 cookie,但有一些方法依賴 cookie。如果第三方 cookie 被阻止,這些方法將會中斷:
如果您的應用程式依賴這些方法中的任何一種,您應該嘗試重寫您的應用程式以避免使用這些方法,或告知您的使用者必須啟用第三方 cookie。 Okta 工程師目前正在研究更好的長期解決方案來解決這個問題。
安裝身份驗證 SDK 很簡單。您可以透過我們的 npm 套件 @okta/okta-auth-js 將其包含在您的專案中。
您還需要:
建立新的 Okta 應用程式時,您可以指定應用程式類型。此 SDK 設計用於與SPA
(單頁應用程式)或Web
應用程式配合使用。 SPA
應用程式將在客戶端執行所有邏輯和授權流程。 Web
應用程式將在伺服器上執行授權流程。
在 Okta 管理 UI 中,按一下Applications
,然後選擇您的應用程式。您可以在應用程式的General
標籤下查看和編輯 Okta 應用程式的配置。
唯一標識您的 Okta 應用程式的字串。
為了讓用戶登錄,您的應用程式會將瀏覽器重定向到 Okta 託管的登錄頁面。然後,Okta 會重定向回您的應用程序,並提供有關用戶的資訊。您可以詳細了解它如何在 Okta 託管的串流上運作。
您需要在 Okta 應用程式設定中將登入重新導向 URL 列入白名單。
當您從應用程式和 Okta 中登出使用者後,您必須將使用者重新導向到應用程式中的特定位置。您需要在 Okta 應用程式設定中將登出後 URL 列入白名單。
如果滿足以下條件,使用我們的 npm 模組是一個不錯的選擇:
要安裝 @okta/okta-auth-js:
# Run this command in your project root folder.
# yarn
yarn add @okta/okta-auth-js
# npm
npm install --save @okta/okta-auth-js
如果您透過瀏覽器在網頁上使用 JS,則可以將node_modules/@okta/okta-auth-js/dist
內容複製到公共託管目錄,並包含對okta-auth-js.min.js
<script>
標記。
建置的庫包也可以在我們的全球 CDN 上取得。在 HTML 檔案中包含以下腳本,以便在應用程式腳本之前載入:
< script src =" https://global.oktacdn.com/okta-auth-js/7.5.1/okta-auth-js.min.js " type =" text/javascript " integrity =" sha384-6epSwnIDkI5zFNEVNjEYy3A7aSZ+C7ehmEyG8zDJZfP9Bmnxc51TK8du+2me4pjb " crossorigin =" anonymous " > </ script >
️ 此範例中顯示的版本可能比目前版本舊。我們建議使用可用的最高版本
然後,您可以建立全域可用的OktaAuth
物件的實例。
const oktaAuth = new OktaAuth ( {
// config
} )
但是,如果您使用 Webpack 或 Rollup 等捆綁程序,則只需匯入或需要該模組即可。
// ES module
import { OktaAuth } from '@okta/okta-auth-js'
const authClient = new OktaAuth ( /* configOptions */ )
// CommonJS
var OktaAuth = require ( '@okta/okta-auth-js' ) . OktaAuth ;
var authClient = new OktaAuth ( /* configOptions */ ) ;
有關客戶端功能和身份驗證流程的概述,請查看我們的開發人員文件。在那裡,您將學習如何在簡單的靜態頁面上使用 Auth SDK 來:
️ 開發人員文件可能是針對該庫的早期版本編寫的。請參閱從先前的版本遷移。
您也可以瀏覽完整的 API 參考文件。
⌛ 非同步方法傳回一個承諾,該承諾將在成功時解決。如果發生錯誤,Promise 可能會被拒絕。
var config = {
issuer : 'https://{yourOktaDomain}/oauth2/default' ,
clientId : 'GHtf9iJdr60A9IYrR0jw' ,
redirectUri : 'https://acme.com/oauth2/callback/home' ,
} ;
var authClient = new OktaAuth ( config ) ;
預設情況下,建立OktaAuth
的新實例不會產生任何非同步副作用。但是,某些功能(例如令牌自動續訂、令牌自動刪除和跨表同步)需要OktaAuth
作為服務運作。這意味著在背景設定超時,它將繼續工作,直到服務停止。若要啟動OktaAuth
服務,只需在建立後、呼叫其他方法(如 handleRedirect)之前呼叫start
方法即可。若要終止所有背景進程,請呼叫stop
。有關詳細信息,請參閱服務配置。
var authClient = new OktaAuth ( config ) ;
await authClient . start ( ) ; // start the service
await authClient . stop ( ) ; // stop the service
注意:啟動服務也會呼叫authStateManager.updateAuthState。
類型定義是透過package.json
中的types
條目隱式提供的。類型也可以透過匯入來明確引用。
import {
OktaAuth ,
OktaAuthOptions ,
TokenManagerInterface ,
AccessToken ,
IDToken ,
UserClaims ,
TokenParams
} from '@okta/okta-auth-js' ;
const config : OktaAuthOptions = {
issuer : 'https://{yourOktaDomain}'
} ;
const authClient : OktaAuth = new OktaAuth ( config ) ;
const tokenManager : TokenManagerInterface = authClient . tokenManager ;
const accessToken : AccessToken = await tokenManager . get ( 'accessToken' ) as AccessToken ;
const idToken : IDToken = await tokenManager . get ( 'idToken' ) as IDToken ;
const userInfo : UserClaims = await authClient . token . getUserInfo ( accessToken , idToken ) ;
if ( ! userInfo ) {
const tokenParams : TokenParams = {
scopes : [ 'openid' , 'email' , 'custom_scope' ] ,
} ;
authClient . token . getWithRedirect ( tokenParams ) ;
}
3.6 之前的 Typescript 版本沒有 WebAuthn 的型別定義。 @okta/[email protected]
中引入了 IDX API 中對 WebAuthn 的支援。若要解決此問題,請安裝套件@types/webappsec-credential-management
version ^0.5.1
。
Web 和本機用戶端可以使用authorization_code
流取得令牌,該流使用儲存在安全位置的用戶端金鑰。 (SPA 應用程式應使用不使用客戶端金鑰的PKCE
流)若要使用authorization_code
流,請將responseType
設為"code"
並將pkce
設為false
:
var config = {
// Required config
issuer : 'https://{yourOktaDomain}/oauth2/default' ,
clientId : 'GHtf9iJdr60A9IYrR0jw' ,
redirectUri : 'https://acme.com/oauth2/callback/home' ,
// Use authorization_code flow
responseType : 'code' ,
pkce : false
} ;
var authClient = new OktaAuth ( config ) ;
預設將使用 PKCE OAuth 流程。該庫支援瀏覽器和 NodeJS 應用程式的 PKCE。在 HTTPS 連線上執行時,大多數現代瀏覽器都廣泛支援 PKCE。 PKCE 要求瀏覽器實作crypto.subtle
(也稱為webcrypto
)。大多數現代瀏覽器在安全上下文中(在 HTTPS 連接上)運行時都會提供此功能。 PKCE 還需要 TextEncoder 物件。除 IE 11 和 Edge < v79 之外,所有主要瀏覽器均可用。為了添加支持,我們建議使用 polyfill/shim,例如文字編碼。
如果使用者的瀏覽器不支援PKCE,則會拋出異常。您可以在建置之前使用以下靜態方法測試瀏覽器是否支援 PKCE:
OktaAuth.features.isPKCESupported()
️ 我們強烈反對使用隱式流程。如果可能,請使用 PKCE 和/或用戶端憑證。
如果您的部署中不支援 PKCE 流,則可以選擇隱式 OAuth 流。它受到大多數瀏覽器的廣泛支持,並且可以在不安全的 HTTP 連接上工作。請注意,隱式流的安全性低於 PKCE 流,即使透過 HTTPS 也是如此,因為原始令牌會在瀏覽器的歷史記錄中公開。因此,如果可能的話,我們強烈建議使用 PKCE 流程。
可以透過將pkce
選項設為false
來啟用隱式串流
var config = {
pkce : false ,
// other config
issuer : 'https://{yourOktaDomain}/oauth2/default' ,
} ;
var authClient = new OktaAuth ( config ) ;
要登入用戶,您的應用程式必須將瀏覽器重定向到 Okta 託管的登入頁面。
注意:初始重定向到 Okta 託管的登入頁面會啟動一個事務,並將 stateToken 生命週期設定為一小時。
身份驗證成功後,瀏覽器將重新導向回您的應用程式以及有關使用者的資訊。根據您的喜好,可以使用以下回調策略。
大多數應用程式將使用與登入頁面分開的特殊路由/頁面來處理 OAuth 回呼。然而,一些 SPA 應用程式沒有路由邏輯,並且希望在單一頁面中處理所有內容。
async function main ( ) {
// create OktaAuth instance
var config = {
issuer : 'https://{yourOktaDomain}/oauth2/default' ,
clientId : 'GHtf9iJdr60A9IYrR0jw' ,
redirectUri : 'https://acme.com/oauth2/callback/home' ,
} ;
authClient = new OktaAuth ( config ) ;
// Subscribe to authState change event.
authClient . authStateManager . subscribe ( function ( authState ) {
// Logic based on authState is done here.
if ( ! authState . isAuthenticated ) {
// render unathenticated view
return ;
}
// Render authenticated view
} ) ;
// Handle callback
if ( authClient . token . isLoginRedirect ( ) ) {
const { tokens } = await authClient . token . parseFromUrl ( ) ; // remember to "await" this async call
authClient . tokenManager . setTokens ( tokens ) ;
}
// normal app startup
authClient . start ( ) ; // will update auth state and call event listeners
}
根據 OAuth 2.0 規範,重定向 URI「不得包含片段元件」:https://tools.ietf.org/html/rfc6749#section-3.1.2 當使用雜湊/片段路由策略和 OAuth 2.0 時,重定向回調將是主要/預設路由。重定向回呼流程與處理沒有路由的回呼非常相似。我們建議在任何其他授權檢查之前定義在應用程式一開始解析重定向 URL 的邏輯。
此外,如果使用雜湊路由,我們建議使用 PKCE 和 responseMode「query」(這是 PKCE 的預設設定)。對於隱式流,雜湊中的令牌可能會導致不可預測的結果,因為雜湊路由器可能會重寫片段。
TokenManager
: tokenManager.setTokens參考:DPoP(演示所有權證明)- RFC9449
DPoP
(指南:配置 DPoP)https
。 WebCrypto.subtle
需要安全上下文IndexedDB
(MDN、caniuse) const config = {
// other configurations
pkce : true , // required
dpop : true ,
} ;
const authClient = new OktaAuth ( config ) ;
參考: DPoP 身份驗證方案(RFC9449)
GET /protectedresource HTTP/1.1
Host: resource.example.org
Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsIm...
async function dpopAuthenticatedFetch ( url , options ) {
const { method } = options ;
const dpop = await authClient . getDPoPAuthorizationHeaders ( { url , method } ) ;
// dpop = { Authorization: "DPoP token****", Dpop: "proof****" }
const headers = new Headers ( { ... options . headers , ... dpop } ) ;
return fetch ( url , { ... options , headers } ) ;
}
use_dpop_nonce
參考:資源伺服器提供的隨機數(RFC9449)
資源伺服器還可以選擇提供一個隨機數值,將其包含在發送給它們的 DPoP 證明中。他們使用 DPoP-Nonce 標頭提供隨機數,就像授權伺服器一樣...
HTTP/1.1 401 Unauthorized
WWW-Authenticate: DPoP error="use_dpop_nonce",
error_description="Resource server requires nonce in DPoP proof"
DPoP-Nonce: eyJ7S_zG.eyJH0-Z.HX4w-7v
async function dpopAuthenticatedFetch ( url , options ) {
// ...previous example...
const resp = await fetch ( url , { ... options , headers } ) ;
// resp = HTTP/1.1 401 Unauthorized...
if ( ! resp . ok ) {
const nonce = authClient . parseUseDPoPNonceError ( resp . headers ) ;
if ( nonce ) {
const retryDpop = await authClient . getDPoPAuthorizationHeaders ( { url , method , nonce } ) ;
const retryHeaders = new Headers ( { ... options . headers , ... retryDpop } ) ;
return fetch ( url , { ... options , headers : retryHeaders } ) ;
}
}
return resp ;
}
DPoP 需要某些瀏覽器功能。使用不具備所需功能的瀏覽器的使用者將無法完成令牌請求。建議在應用程式引導期間驗證瀏覽器支援。
// App.tsx
useEffect ( ( ) => {
if ( ! authClient . features . isDPoPSupported ( ) ) {
// user will be unable to request tokens
navigate ( '/unsupported-error-page' ) ;
}
} , [ ] ) ;
DPoP 需要產生需要持久保存在儲存中的CryptoKeyPair
。像signOut()
或revokeAccessToken()
這樣的方法將清除金鑰對,但是使用者並不總是明確登出。因此,最好在登入之前清除存儲,以刷新從先前請求的令牌生成的任何孤立密鑰對。
async function login ( options ) {
await authClient . clearDPoPStorage ( ) ; // clear possibly orphaned key pairs
return authClient . signInWithRedirect ( options ) ;
}
無論您是使用此 SDK 實現 OIDC 流程還是與身份驗證 API 進行通信,唯一需要的配置選項是issuer
,它是 Okta 授權伺服器的 URL
您可以使用 Okta 組織的 URL 作為發行者。這將套用預設授權策略並頒發組織層級範圍內的令牌。
var config = {
issuer : 'https://{yourOktaDomain}'
} ;
var authClient = new OktaAuth ( config ) ;
Okta 可讓您建立多個自訂 OAuth 2.0 授權伺服器,您可以使用它們來保護自己的資源伺服器。在每個授權伺服器中,您可以定義自己的 OAuth 2.0 範圍、聲明和存取策略。許多組織都有一個「預設」授權伺服器。
var config = {
issuer : 'https://{yourOktaDomain}/oauth2/default'
} ;
var authClient = new OktaAuth ( config ) ;
您也可以建立和自訂其他授權伺服器。
var config = {
issuer : 'https://{yourOktaDomain}/oauth2/custom-auth-server-id'
} ;
var authClient = new OktaAuth ( config ) ;
實例化 Okta Auth JS ( new OktaAuth(config)
) 時可以包含這些選項。
issuer
️ 此選項為必填項
您的 Okta 組織或 Okta 身份驗證伺服器的 URL。關於發行人
clientId
已向 Okta 預先註冊 OIDC 身份驗證流程的用戶端 ID。創建您的 Okta 應用程式
redirectUri
使用token.getWithRedirect
時重定向到的 url。這必須列在您的 Okta 應用程式的登入重定向 URI 中。如果未提供redirectUri
,則預設為目前原點( window.location.origin
)。配置您的 Okta 應用程式
postLogoutRedirectUri
指定退出後瀏覽器應重定向到的 URL。此 URL 必須列在您的 Okta 應用程式的登出重定向 URI 中。如果未指定,將使用應用程式的原點 ( window.location.origin
)。配置您的 Okta 應用程式 |
scopes
指定在傳回的id_token
或access_token
中提供哪些資訊。對於 OIDC,您必須將openid
包含為範圍之一。預設為['openid', 'email']
。有關可用範圍的列表,請參閱範圍和聲明
state
客戶端提供的字串,將傳遞到伺服器端點並在 OAuth 回應中傳回。該值可用於驗證 OAuth 回應並防止跨站點請求偽造 (CSRF)。預設為隨機字串。
pkce
預設值為true
,這將啟用 PKCE OAuth 流程。若要使用隱式流或授權代碼流,請將pkce
設定為false
。
dpop
預設值為false
。設定為true
以啟用DPoP
(演示所有權證明 (RFC9449))
請參閱指南:啟用 DPoP
當使用 token.getWithRedirect 請求令牌時,值將作為附加到redirectUri 的參數傳回。
在大多數情況下,您不需要為responseMode
設定值。預設值根據 OpenID Connect 1.0 規格設定。
對於 PKCE OAuth Flow),授權代碼將位於 URL 的搜尋查詢中。使用 PKCE 流的用戶端可以選擇將 responseMode 選項設為「fragment」來接收雜湊片段中的授權程式碼。
對於隱式 OAuth 流),令牌將位於 URL 的雜湊片段中。這是無法改變的。
responseType
使用隱式 OAuth 流程時指定 OIDC 驗證的回應類型。預設值為['token', 'id_token']
它將請求存取令牌和 ID 令牌。如果pkce
為true
,則將請求存取令牌和 ID 令牌,並且將忽略此選項。對於使用authorization_code
流程的Web/本機應用程序,該值應設定為"code"
, pkce
應設定為false
。
authorizeUrl
指定自訂authorizeUrl來執行OIDC流程。預設為頒發者加“/v1/authorize”。
userinfoUrl
指定自訂 userinfoUrl。預設為頒發者加“/v1/userinfo”。
tokenUrl
指定自訂 tokenUrl。預設為發行者加“/v1/token”。
ignoreSignature
️ 此選項應僅用於瀏覽器支援和測試目的。
預設情況下,當呼叫token.getWithoutPrompt
、 token.getWithPopup
、 token.getWithRedirect
和token.verify
時,會驗證 ID 令牌簽署。若要停用這些方法的 ID 令牌簽章驗證,請將此值設為true
。
maxClockSkew
預設為 300(五分鐘)。這是驗證令牌時用戶端時鐘與 Okta 時鐘之間允許的最大差異(以秒為單位)。不建議將此值設為 0,因為它會增加有效令牌驗證失敗的可能性。
ignoreLifetime
️ 此選項可停用令牌生命週期驗證,這可能會引入安全漏洞問題。此選項應用於測試目的。請在您自己的生產環境應用程式中處理錯誤。
令牌生命週期使用 maxClockSkew 進行驗證。若要覆寫此設定並停用令牌生命週期驗證,請將此值設為true
。
transformAuthState
回調函數。當呼叫 updateAuthState 時,會產生一個新的 authState 物件。提供transformAuthState
函數可讓您在儲存和發出該物件之前修改或取代該物件。一個常見的用例是更改 isAuthenticated 的含義。預設情況下,如果 tokenManager 中有未過期的令牌,則updateAuthState
會將authState.isAuthenticated
設為 true。可以自訂此邏輯以還需要有效的 Okta SSO 會話:
const config = {
// other config
transformAuthState : async ( oktaAuth , authState ) => {
if ( ! authState . isAuthenticated ) {
return authState ;
}
// extra requirement: user must have valid Okta SSO session
const