瞭解 Node.js 應用程式與 Oracle Identity Cloud Service 之間的認證
您已經準備好瞭解 Node.js Web 應用程式與 Oracle Identity Cloud Service 之間的認證。其中包括瞭解下列各項:
-
Oracle Identity Cloud Service 支援 Node.js SDK 的三方認證流程
-
使用具有 Node.js 應用程式的 SDK 與 Oracle Identity Cloud Service 進行認證的使用案例
-
Node.js SDK 的方法和功能
瞭解三方認證流程
Oracle Identity Cloud Service 支援 Node.js SDK 的三方認證流程。在此流程中,使用者會直接與 Oracle Identity Cloud Service 互動。使用者登入之後,Oracle Identity Cloud Service 會發出 SDK 交換使用者存取權杖的授權碼。Node.js Web 應用程式會使用此存取權杖來授予使用者應用程式中受保護資源的存取權。三方流程使用授權代碼授權類型。
為了提高安全性,Oracle 建議您使用三方流程,將您的 Node.js Web 應用程式與 Oracle Identity Cloud Service 整合以進行驗證。透過使用授權碼授權類型,您也可以存取受 Oracle Identity Cloud Service 保護的其他應用程式,而不需要重新認證。
瞭解搭配 Node.js 應用程式使用 SDK 的主要使用案例
Node.js Web 應用程式實行兩種使用案例:一個用於認證使用者,另一個用於存取登入使用者的詳細資訊。
下列資料流程圖說明每個使用案例的 Web 瀏覽器、Web 應用程式和 Oracle Identity Cloud Service 之間事件、呼叫和回應的流程。
使用案例 #1:驗證使用者
資料流程會發生下列情況:
-
使用者要求受保護的資源。
-
認證模組會使用 SDK 產生 Oracle Identity Cloud Service 的要求授權碼 URL,並將此 URL 作為 Web 瀏覽器的重新導向回應傳送。
-
Web 瀏覽器會呼叫 URL。
-
Oracle Identity Cloud Service 登入頁面便會顯示。
-
使用者會送出其 Oracle Identity Cloud Service 登入證明資料。
-
使用者登入之後,Oracle Identity Cloud Service 會為使用者建立階段作業並發出授權碼。
-
Web 應用程式會進行後端 (或伺服器對伺服器) 呼叫,以交換存取權杖的授權碼。
-
Oracle Identity Cloud Service 會發出存取權杖和 ID 權杖。
-
階段作業會建立,並將使用者重新導向至首頁。
-
Web 應用程式的首頁便會顯示。
使用案例 #2:取得使用者的相關明細
資料流程會發生下列情況:
-
使用者要求
/myProfile
資源。 -
Web 應用程式使用 Oracle Identity Cloud Service 的 SDK 來驗證 ID 權杖。
-
從 ID 權杖驗證傳回的資料包含以 JSON 物件格式的使用者詳細資訊。
-
我的設定檔頁面會將 JSON 物件轉譯為 HTML 內容。
瞭解方法和函數
Node.js SDK 是您新增至 Node.js modules
資料夾的 Node.js 護照策略。此 SDK 也以 Node.js 承諾為基礎。
從 Oracle Identity Cloud Service 主控台下載之 Node.js SDK 壓縮檔內的 SDK package.json
檔案中,定義 Node.js SDK 所需的所有第三方相依性。您至少必須在 Node.js Web 應用程式中使用此組模組。
"dependencies": {
"async": "^2.1.2",
"bunyan": "^1.8.5",
"cache-manager": "^2.2.0",
"json-web-token": "^2.1.3",
"jsonwebtoken": "^8.2.1",
"jwk-to-pem": "^1.2.6",
"jws": "^3.1.5",
"lru": "^3.1.0",
"passport": "^0.4.0",
"promise": "^8.0.1",
"querystring": "^0.2.0",
"request": "^2.81.0",
"rsa-pem-to-jwk": "^1.1.3",
"util": "^0.10.3"
},
Node.js Web 應用程式是使用 Node.js express
和 express-handlebars
模組開發的,此模組會以每個 URL 的 app.get()
函數形式實行 URL 路由。
Node.js SDK 需要載入 Oracle Identity Cloud Service 連線資訊的 JSON 變數。Node.js Web 應用程式使用 ids
變數來儲存此資訊:
var ids = {
oracle: {
"ClientId": "123456789abcdefghij'",
"ClientSecret": "abcde-12345-zyxvu-98765-qwerty",
"ClientTenant": "idcs-abcd1234",
"IDCSHost": "https://%tenant%.identity.oraclecloud.com",
"AudienceServiceUrl" : "https://idcs-abcd1234.identity.oraclecloud.com",
"TokenIssuer": "https://identity.oraclecloud.com/",
"scope": "urn:opc:idm:t.user.me openid",
"logoutSufix": "/oauth2/v1/userlogout",
"redirectURL": "http://localhost:3000/callback",
"LogLevel":"INFO",
"ConsoleLog":"True"
}
};
module.exports = ids;
以下是此 SDK 之每個必要屬性的簡要說明:
名稱 | 描述 |
---|---|
ClientId |
在 Oracle Identity Cloud Service 主控台中註冊 Node.js Web 應用程式後所產生的「從屬端 ID」值。 |
ClientSecret |
在 Oracle Identity Cloud Service 主控台中註冊 Node.js Web 應用程式後所產生的「從屬端加密密碼」值。 |
ClientTenant |
您 Oracle Identity Cloud Service 執行處理的網域前置碼。此前置碼通常類似於 idcs-abcd1234 。
|
IDCSHost |
您 Oracle Identity Cloud Service 執行處理的網域字尾。在程式實際執行時, %tenant% 預留位置會被 ClientTenant 屬性的值取代。 |
AudienceServiceUrl |
您 Oracle Identity Cloud Service 執行處理的完整網域名稱 URL。 |
TokenIssuer |
對於此屬性,Oracle 建議您保留值 https://identity.oraclecloud.com/ 。
|
scope |
範圍控制應用程式可代表 Oracle Identity Cloud Service 使用者存取或處理的資料。 如果應用程式使用 SDK 來認證使用者,則範圍為 |
ConsoleLog |
啟用 SDK 日誌。 |
LogLevel |
指示 SDK 的日誌層次。 |
應用程式會使用 logoutSufix
和 redirectURL
屬性來避免硬式編碼這些值。SDK 不需要。
Node.js 應用程式會實行 /oauth/oracle
URL 路由。使用者使用 Oracle Identity Cloud Service 進行認證時,Web 瀏覽器會對此 URL 進行 GET 要求。此路由會使用 SDK 產生 Oracle Identity Cloud Service 的授權 URL。
//Loading the configurations
var auth = require('./auth.js');
//Route for /oauth/oracle
app.get("/auth/oracle", function(req, res){
//Authentication Manager loaded with the configurations.
am = new IdcsAuthenticationManager(auth.oracle);
//Using Authentication Manager to generate the Authorization Code URL, passing the
//application's callback URL as parameter, along with code value and code parameter.
am.getAuthorizationCodeUrl(auth.oracle.redirectURL, auth.oracle.scope, "1234", "code")
.then(function(authZurl){
//Redirecting the browser to the Oracle Identity Cloud Service Authorization URL.
res.redirect(authZurl);
}).catch(function(err){
res.end(err);
})
});
此函數會將 JSON 參數載入變數、起始認證管理程式,以及使用 Node.js SDK 的 IdcsAuthenticationManager.getAuthorizationCodeUrl()
函數來產生授權代碼 URL。當產生授權碼 URL 或在瀏覽器中呈現錯誤時,此函數會使用承諾來重新導向使用者的 Web 瀏覽器。
下列參數是用來產生授權碼 URL:
名稱 | 描述 |
---|---|
auth.oracle.redirectURL |
使用者登入之後,Oracle Identity Cloud Service 會將使用者的 Web 瀏覽器重新導向至此 URL。此 URL 必須與您在 Identity Cloud Service 主控台中為信任應用程式設定的 URL 相符。如需有關為 Node.js Web 應用程式指定重新導向 URL 的詳細資訊,請參閱註冊 Node.js 應用程式。 |
auth.oracle.scope |
認證的 OAuth 或 OpenID Connect 範圍。此應用程式只需要 openid 認證。
|
state |
OAuth 協定會定義此參數。範例 Node.js Web 應用程式會使用此程式碼來檢查是否可以建立與 Oracle Identity Cloud Service 的通訊。在此範例中,此參數的值為 1234 。
|
response_type |
授權代碼授予類型所需的參數。在此範例中,此參數的值為 code 。
|
使用者登入之後,Oracle Identity Cloud Service 會將使用者的 Web 瀏覽器重新導向開發人員必須實行的回呼 URL。Node.js Web 應用程式使用 /callback
路由來處理此要求。
//Route for /callback
app.get("/callback", function(req,res){
//Authentication Manager loaded with the configurations.
var am = new IdcsAuthenticationManager(auth.oracle);
//Getting the authorization code from the "code" parameter
var authZcode = req.query.code;
//Using the Authentication Manager to exchange the Authorization Code to an Access Token.
am.authorizationCode(authZcode)
.then(function(result){
//Getting the Access and Id Token Values to set in the session.
req.session.access_token = result.access_token;
req.session.id_token = result.id_token;
res.cookie(config.IDCS_COOKIE_NAME, result.access_token);
res.header('idcs_user_assertion', result.access_token)
res.redirect('/auth.html');
}).catch(function(err){
res.end(err);
})
});
Node.js 應用程式會使用授權碼來要求存取權杖。存取記號會儲存為 Cookie,然後傳送至 Web 瀏覽器供未來使用。
Node.js SDK 的 IdcsAuthenticationManager.authorizationCode()
函數也使用 promise (then-catch 敘述句) 將存取記號設為 Cookie,並將瀏覽器重新導向至 /auth.html
頁面。
Node.js SDK 是以 Node.js 護照架構為基礎。因此,瀏覽器必須將存取權杖作為標頭變數轉送至 /auth
URL 處理程式,並使用 passport.authenticate()
方法搭配 Oracle Identity Cloud Service 策略名稱作為參數:
//Uses passport to create a User Session in Node.js.
//Passport sets a user attribute in the request as a json object.
app.get('/auth', passport.authenticate(config.IDCS_STRATEGY_NAME, {}), function(req, res) {
res.redirect('/home');
});
在 passport.authenticate()
方法建立應用程式的階段作業之後,此函數會將使用者的 Web 瀏覽器重新導向至 /home
應用程式中的受保護 URL。除了 /home
之外,Node.js Web 應用程式還有另一個受保護的 URL:/myProfile
。
任何受保護的 URL 都必須檢查先前是否已建立使用者的階段作業。這些 URL 的每個 app.get()
函數都會使用下列函數。
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login')
}
Node.js 應用程式會處理 /myProfile
路由,並取得階段作業中設定的資訊,如下所示:
app.get("/myProfile", ensureAuthenticated, function(req,res){
//User Manager loaded with the configurations
var am = new IdcsAuthenticationManager(auth.oracle);
//Validating id token to acquire information such as UserID, DisplayName, list of groups and AppRoles assigned to the user.
am.validateIdToken(req.session['id_token'])
.then(function(idToken){
res.render('myProfile', {
layout: 'privateLayout',
title: 'My Profile',
user: req.user,
userInfo: JSON.stringify(idToken, null, 2)
});
}).catch(function(err1){
res.end(err1);
})
});
初始化 IdcsAuthenticationManager
物件之後,/myProfile
路由的處理程式會使用 SDK 的 IdcsAuthenticationManager.validateIdToken()
函數來取得使用者資訊,例如顯示名稱、使用者 ID,以及指派給使用者的群組和應用程式角色清單。然後,JSON 物件會以字串形式剖析為 myProfile.handlebars
檔案,以便在 Web 瀏覽器中轉譯。
若要將使用者從應用程式與 Oracle Identity Cloud Service 之間的單一登入登出,Node.js Web 應用程式會實行 /logout
路由,如下所示:
app.get('/logout', function(req, res){
var id_token = req.session.id_token;
var logouturl = auth.oracle.AudienceServiceUrl + auth.oracle.logoutSufix + '?post_logout_redirect_uri=http%3A//localhost%3A3000&id_token_hint='+ id_token;
req.session.destroy(function(err) {
if(err) {
console.log(err);
} else {
req.logout();
res.clearCookie();
res.redirect(logouturl);
}
})
});
此路由會讓應用程式的階段作業失效、移除先前設定的所有物件和 Cookie,然後將使用者的 Web 瀏覽器重新導向至 Oracle Identity Cloud Service 的 OAuth 登出 URL。