개발이야기/AspNet&C#

IdentityServer 학습 #10 - BFF without backend

Roslyn 2024. 3. 11. 11:38
반응형

본문 글은 원문(https://docs.duendesoftware.com/identityserver/v7/quickstarts/js_clients/js_without_backend/)을 참고하여 작성되었습니다.

 

(1) 먼저 사용할 프로젝트를 생성해 줍니다.  (예시에서는 SPA)

dotnet new web -n SPA

 

(2) 해당 프로젝트를 솔루션에 추가해 줍니다.

dotnet sln add ./{프로젝트경로}

 

(3) wwwroot 디렉토리를 만들어 주고, package.json 파일을 생성해 줍니다.

npm init

 

(4) oidc-client 라이브러리를 설치해 줍니다. (시작파일은 app.js로 지정)

npm i oidc-client

 

(5) 설치된 라이브러리에 있는 js 파일을 wwwroot 로 복사해 옵니다.

copy node_modules\oidc-client\dist\* .

 

(6) index.html 파일을 추가해 줍니다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <button id="login">Login</button>
    <button id="api">Call API</button>
    <button id="logout">Logout</button>

    <pre id="results"></pre>

    <script src="oidc-client.js"></script>
    <script src="app.js"></script>
</body>
</html>

 

(7) callback.html 파일을 추가해 줍니다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <script src="oidc-client.js"></script>
    <script>
        new Oidc.UserManager({response_mode:"query"}).signinRedirectCallback().then(function() {
            window.location = "index.html";
        }).catch(function(e) {
            console.error(e);
        });
    </script>
</body>
</html>

 

(8) app.js 파일을 추가해 줍니다.

function log() {
    document.getElementById("results").innerText = "";

    Array.prototype.forEach.call(arguments, function (msg) {
        if (typeof msg !== "undefined") {
            if (msg instanceof Error) {
                msg = "Error: " + msg.message;
            } else if (typeof msg !== "string") {
                msg = JSON.stringify(msg, null, 2);
            }
            document.getElementById("results").innerText += msg + "\r\n";
        }
    });
}

document.getElementById("login").addEventListener("click", login, false);
document.getElementById("api").addEventListener("click", api, false);
document.getElementById("logout").addEventListener("click", logout, false);

var config = {
    authority: "https://localhost:5001",
    client_id: "js",
    redirect_uri: "https://localhost:5003/callback.html",
    response_type: "code",
    scope: "openid profile api1",
    post_logout_redirect_uri: "https://localhost:5003/index.html",
};
var mgr = new Oidc.UserManager(config);

mgr.events.addUserSignedOut(function () {
    log("User signed out of IdentityServer");
});

mgr.getUser().then(function (user) {
    if (user) {
        log("User logged in", user.profile);
    } else {
        log("User not logged in");
    }
});

function login() {
    mgr.signinRedirect();
}

function api() {
    mgr.getUser().then(function (user) {
        var url = "https://localhost:6001/identity";

        var xhr = new XMLHttpRequest();
        xhr.open("GET", url);
        xhr.onload = function () {
            log(xhr.status, JSON.parse(xhr.responseText));
        };
        xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
        xhr.send();
    });
}

function logout() {
    mgr.signoutRedirect();
}

 

(9) IdentityServer에 Client를 추가해 줍니다.

new Client
{
    ClientId = "js",
    ClientName = "JavaScript Client",
    AllowedGrantTypes = GrantTypes.Code,
    RequireClientSecret = false,

    RedirectUris =           { "https://localhost:5003/callback.html" },
    PostLogoutRedirectUris = { "https://localhost:5003/index.html" },
    AllowedCorsOrigins =     { "https://localhost:5003" },

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        "api1"
    }
}

 

(10) HostingExtensions.cs 파일을 열어 서비스에 Cors 관련 설정을 추가해 줍니다.

builder.Services.AddCors(options =>
{
    // this defines a CORS policy called "default"
    options.AddPolicy("default", policy =>
    {
        policy.WithOrigins("https://localhost:5003")
            .AllowAnyHeader()
            .AllowAnyMethod();
    });
});

 

(11) 추가된 Cors설정을 ConfigurePipline 함수에서 사용해 줍니다.

app.UseHttpsRedirection();
app.UseCors("default");

 

(12) 동일한 Cors 관련 작업을 api 서버에도 추가해 줍니다.

 

(13) 실행하면 다음과 같은 화면이 나옵니다.

 

(14) 로그인 버튼을 누르면 로그인을 하면 원래 페이지로 되돌아와서 정보가 표시됩니다.

 

(15) Call API 버튼을 누르면 정상적으로 API 정보를 받아옵니다.

반응형