Node.js 애플리케이션과 Oracle Identity Cloud Service 간의 인증에 대해 알아보기

Node.js 웹 애플리케이션과 Oracle Identity Cloud Service 간의 인증에 대해 알아볼 준비가 되었습니다. 여기에는 다음 사항을 이해하는 것이 포함됩니다.

  • Oracle Identity Cloud Service가 Node.js SDK에 대해 지원하는 3단계 인증 플로우입니다.

  • Node.js 애플리케이션과 함께 SDK를 사용하여 Oracle Identity Cloud Service로 인증하는 사용 사례

  • Node.js SDK의 방법 및 기능

3단계 인증 플로우에 대해 알아보기

Oracle Identity Cloud Service는 Node.js SDK에 대해 3단계 인증 플로우를 지원합니다. 이 플로우에서 사용자는 Oracle Identity Cloud Service와 직접 상호작용합니다. 사용자가 사인인한 후 Oracle Identity Cloud Service는 SDK가 사용자 액세스 토큰을 교환하는 권한 부여 코드를 발행합니다. Node.js 웹 애플리케이션은 이 액세스 토큰을 사용하여 애플리케이션에서 보호된 리소스에 대한 액세스 권한을 사용자에게 부여합니다. 3단계 플로우는 권한 부여 코드 권한 부여 유형을 사용합니다.

보안을 강화하기 위해 Oracle은 3단계 플로우를 사용하여 인증을 위해 Node.js 웹 애플리케이션을 Oracle Identity Cloud Service와 통합할 것을 권장합니다. 권한 부여 코드 유형을 사용하여 다시 인증하지 않고도 Oracle Identity Cloud Service로 보호되는 다른 애플리케이션에 액세스할 수도 있습니다.

Node.js 애플리케이션에서 SDK를 사용하는 주요 사용 사례에 대해 알아보기

Node.js 웹 애플리케이션은 두 가지 사용 사례를 구현합니다. 하나는 사용자 인증용이고 다른 하나는 로그인한 사용자에 대한 자세한 정보에 액세스하기 위한 것입니다.

다음 데이터 플로우 다이어그램은 각 사용 사례에 대한 웹 브라우저, 웹 애플리케이션 및 Oracle Identity Cloud Service 간의 이벤트, 호출 및 응답 플로우를 보여 줍니다.

사용 사례 #1: 사용자 인증

데이터 흐름은 다음과 같이 발생합니다.

  1. 사용자가 보호된 리소스를 요청합니다.

  2. 인증 모듈은 SDK를 사용하여 Oracle Identity Cloud Service에 대한 요청 권한 부여 코드 URL을 생성하고 이 URL을 웹 브라우저에 재지정 응답으로 전송합니다.

  3. 웹 브라우저가 URL을 호출합니다.

  4. Oracle Identity Cloud Service 사인인 페이지가 나타납니다.

  5. 사용자가 Oracle Identity Cloud Service 사인인 인증서를 제출합니다.

  6. 사용자가 사인인한 후 Oracle Identity Cloud Service는 사용자에 대한 세션을 생성하고 권한 부여 코드를 발행합니다.

  7. 웹 응용 프로그램은 액세스 토큰에 대한 권한 부여 코드를 교환하기 위해 백엔드(또는 서버 간) 호출을 수행합니다.

  8. Oracle Identity Cloud Service가 액세스 토큰 및 ID 토큰을 발행합니다.

  9. 세션이 설정되고 사용자가 페이지로 재지정됩니다.

  10. 웹 애플리케이션의 페이지가 나타납니다.

사용 사례 #2: 사용자에 대한 세부정보 가져오기

데이터 흐름은 다음과 같이 발생합니다.

  1. 사용자가 /myProfile 리소스를 요청합니다.

  2. 웹 애플리케이션은 Oracle Identity Cloud Service의 SDK를 사용하여 ID 토큰을 검증합니다.

  3. ID 토큰 검증에서 반환되는 데이터는 JSON 객체 형식의 사용자 세부정보를 포함합니다.

  4. 내 프로파일 페이지는 JSON 객체를 HTML 콘텐츠로 렌더링합니다.

메소드 및 함수에 대해 알아보기

Node.js SDK는 Node.js modules 폴더에 추가하는 Node.js 여권 전략입니다. 이 SDK는 또한 Node.js 약속을 기반으로합니다.

Node.js SDK에 필요한 모든 타사 종속성은 Oracle Identity Cloud Service 콘솔에서 다운로드하는 Node.js SDK zip 파일 내 SDK의 package.json 파일에 정의되어 있습니다. Node.js 웹 애플리케이션에서 이 모듈 세트를 하나 이상 사용해야 합니다.

"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 웹 애플리케이션은 각 URL에 대해 URL 경로를 app.get() 함수 형식으로 구현하는 Node.js expressexpress-handlebars 모듈을 사용하여 개발되었습니다.

Node.js SDK를 사용하려면 Oracle Identity Cloud Service 접속 정보와 함께 로드된 JSON 변수가 필요합니다. Node.js 웹 애플리케이션은 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 웹 애플리케이션을 등록한 후 생성되는 클라이언트 ID 값입니다.
ClientSecret Oracle Identity Cloud Service 콘솔에서 Node.js 웹 애플리케이션을 등록한 후 생성되는 클라이언트 암호 값입니다.
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를 사용하여 사용자를 인증하는 경우 범위는 openid입니다. 애플리케이션이 SDK를 사용하여 사용자에 대한 세부정보를 가져오는 경우 범위는 urn:opc:idm:t.user.me openid입니다.

ConsoleLog SDK 로그를 사용으로 설정합니다.
LogLevel SDK의 로그 레벨을 나타냅니다.

응용 프로그램은 이러한 값을 하드 코딩하지 않도록 logoutSufixredirectURL 속성을 모두 사용합니다. SDK는 필요하지 않습니다.

Node.js 애플리케이션은 /oauth/oracle URL 경로를 구현합니다. 사용자가 Oracle Identity Cloud Service를 사용하여 인증하면 웹 브라우저가 이 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이 생성될 때 사용자 웹 브라우저를 재지정하거나 브라우저에서 오류를 렌더링하기 위해 약속을 사용합니다.

인증 코드 URL을 생성하는 데 사용되는 매개변수는 다음과 같습니다.

이름 설명
auth.oracle.redirectURL 사용자가 사인인하면 Oracle Identity Cloud Service는 사용자의 웹 브라우저를 이 URL로 재지정합니다. 이 URL은 Identity Cloud Service 콘솔에서 신뢰할 수 있는 애플리케이션에 대해 구성할 URL과 일치해야 합니다. Node.js 웹 애플리케이션의 재지정 URL 지정에 대한 자세한 내용은 Node.js 애플리케이션 등록을 참조하십시오.
auth.oracle.scope 인증의 OAuth 또는 OpenID Connect 범위입니다. 이 애플리케이션에는 openid 인증만 필요합니다.
state OAuth 프로토콜은 이 매개변수를 정의합니다. 샘플 Node.js 웹 애플리케이션은 이 코드를 사용하여 Oracle Identity Cloud Service에 대한 통신을 설정할 수 있는지 여부를 확인합니다. 이 예에서 이 매개변수의 값은 1234입니다.
response_type 승인 코드 부여 유형에 필요한 매개변수입니다. 이 예에서 이 매개변수의 값은 code입니다.

사용자가 사인인한 후 Oracle Identity Cloud Service는 사용자의 웹 브라우저를 개발자가 구현해야 하는 콜백 URL로 재지정합니다. Node.js 웹 애플리케이션은 /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 애플리케이션은 권한 부여 코드를 사용하여 액세스 토큰을 요청합니다. 액세스 토큰은 쿠키로 저장되고 나중에 사용할 수 있도록 웹 브라우저로 전송됩니다.

또한 Node.js SDK의 IdcsAuthenticationManager.authorizationCode() 함수는 promise( then-catch 문)를 사용하여 액세스 토큰을 쿠키로 설정하고 브라우저를 /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() 메소드가 애플리케이션의 세션을 생성한 후 함수는 사용자의 웹 브라우저를 /home 애플리케이션의 보호된 URL로 재지정합니다. /home 외에도 Node.js 웹 애플리케이션에는 다른 보호 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 파일에 문자열로 구문 분석됩니다.

애플리케이션과 Oracle Identity Cloud Service 간의 Single Sign-On에서 사용자를 사인아웃하기 위해 Node.js 웹 애플리케이션은 다음과 같이 /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);
    }
  })
});

이 경로는 애플리케이션 세션을 무효화하고, 이전에 설정된 객체 및 쿠키를 제거한 다음, 사용자의 웹 브라우저를 Oracle Identity Cloud Service의 OAuth 로그아웃 URL로 재지정합니다.