본문 바로가기

ASP.NET Blazor

Blazor/ASP.NET 구글 인증 로그인 만들기 - 3. 구글 인증 처리 코드 작성

목차

1. 프로젝트 세팅

2. 구글 클라우드 API 프로젝트 세팅

3. 구글 인증 처리 코드 작성

4. 구글 계정 정보 페이지에 띄우기

 

 

코드를 작성하기 앞서 필요한 패키지가 있습니다.

 

Nuget 패키지 설치

도구 - Nuget 패키지 관리자 - 솔루션용 Nuget 패키지 관리

 

찾아보기 탭에서 google을 검색하고 Microsoft.AspNetCore.Authentication.Google을 선택합니다.

 

프로젝트에 체크하고 버전을 선택합니다.

프로젝트가 Net 6.0 버전이기 때문에 패키지도 6으로 시작하는 버전을 선택합니다.

(7.0인경우 7 선택)

 

 

코드 작성

1. 모델 작성

Google 폴더를 생성하고 GoogleUser C# 클래스를 생성하고 아래와 같이 작성합니다.

namespace GoogleOAuthSample.Google
{
    public static class Google
    {
        public static GoogleUser Data { get; set; }
    }

    public class GoogleUser
    {
        public string ID { get; set; }

        public string AccessToken { get; set; }

        public string RefreshToken { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string Email { get; set; }

        public string ImageUrl { get; set; }
    }
}

 

예시

 

2. 인증 서비스 추가

Program.cs의 builder 파트에 인증 서비스를 추가합니다.

// Google Login OAuth
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(opt =>
    {
        opt.Cookie.Name = "GoogleOAuth";
    })
    .AddGoogle(opt =>
    {
        opt.ClientId = builder.Configuration["Authentication:Google:ClientId"];
        opt.ClientSecret = builder.Configuration["Authentication:Google:ClientSecret"];

        // OAuth 인증 시 어떤 권한을 포함할지를 정하는 Scope.
        // Scope URL은 Google에서 정의된 값을 넣어준다.
        opt.Scope.Add("openid");
        opt.Scope.Add("https://www.googleapis.com/auth/userinfo.email");
        opt.Scope.Add("https://www.googleapis.com/auth/userinfo.profile");

        // AccessType에 대한 정의는 찾아보면 자세히 나와있다.
        // default값은 online이며, RefreshToken을 얻기위해서는 offline으로 지정해줘야 함.
        opt.AccessType = "offline";

        // Code 발급 후 Token 취득까지 해당 Warpper가 처리해준다.
        // 이 이벤트는 Token까지 취득 후 발생한다.
        opt.Events.OnCreatingTicket = context =>
        {
            var user = new GoogleUser()
            {
                ID = context.User.GetProperty("id").GetString(),
                AccessToken = context.AccessToken,
                RefreshToken = context.RefreshToken,
                FirstName = context.User.GetProperty("family_name").GetString(),
                LastName = context.User.GetProperty("given_name").GetString(),
                Email = context.User.GetProperty("email").GetString(),
                ImageUrl = context.User.GetProperty("picture").GetString(),
            };

            Google.Data = user; // 인증을 통해 얻은 구글 유저 데이터를 저장하여 사용

            return Task.CompletedTask;
        };
    });

 

app 파트에는 아래 코드를 추가합니다.

app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

 

 

3. 컨트롤러 작성

Google 폴더에 GoogleAuthController 클래스를 생성합니다.

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.Google;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;

namespace GoogleOAuthSample.Google
{
    [Route("/api/auth")]
    [ApiController]
    public class GoogleAuthController : ControllerBase
    {
        [HttpGet("google/login")]
        public ActionResult GoogleLogin()
        {
            var properties = new AuthenticationProperties()
            {
                RedirectUri = "/",

                // prompt=consent : 매번 권한 요청 및 승인 시 RefreshToken 획득
                // prompt=login : 최초 권한 승인만 RefreshToken 획득
                Parameters = { { "prompt", "consent" } },
            };
            return Challenge(properties, GoogleDefaults.AuthenticationScheme);
        }

        [HttpGet("google/logout")]
        public async Task<ActionResult> GoogleLogout()
        {
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            Google.Data = null;
            return LocalRedirect("/");
        }
    }
}

 

4. 리다이렉트 페이지 추가

Google 폴더에 GoogleLogin.razor 그리고 GoogleLogout.razor 파일을 생성합니다.

 

GoogleLogin.razor

@page "/signin-google"

@inject NavigationManager NavigationManager
@attribute [AllowAnonymous]

@{
    NavigationManager.NavigateTo("api/auth/google/login", true);
}

 

GoogleLogout.razor

@page "/signout-google"

@inject NavigationManager NavigationManager

@{
	NavigationManager.NavigateTo("api/auth/google/logout", true);
}

 

 

5. 로그인/로그아웃 페이지 연결

 

기존에 작성해두었던 Index.razor의 Login/Logout 함수에 위에서 작성한 페이지로 이동하는 코드를 작성합니다.

@page "/"
@inject NavigationManager NavigationManager

<button class="btn btn-primary" @onclick="Login">구글 로그인</button>
<button class="btn btn-primary" @onclick="Logout">구글 로그아웃</button>

@code {

    private void Login()
    {
        NavigationManager.NavigateTo("signin-google");
    }

    private void Logout()
    {
        NavigationManager.NavigateTo("signout-google");
    }
}

 

테스트

서버를 실행하여 구글 로그인/로그아웃이 정상적으로 동작하는지 테스트를 진행합니다.

 

 

서버가 실행되면 자동으로 별도의 브라우저가 실행되어 페이지가 나타나게 되는데, 외부 프로그램에 의해 제어받는 브라우저에서는 구글 인증을 정상적으로 수행할 수 없습니다.

 

따라서, 직접 실행된 브라우저에서 해당 주소로 이동하여야 합니다.

 

현재 사용하고 있는 브라우저에서 접속했습니다.

 

구글 로그인 버튼을 클릭해봅니다!

 

위와 같은 익숙한 구글 로그인 페이지가 나타나면 성공입니다.

이 페이지에서는 OAuth 동의 화면에서 세팅한 요소들이 사용자에게 보여집니다.

 

로그인을 진행합니다.

 

겉보기엔 페이지에 변화가 없어 아무런 일도 일어나지 않은 것 같지만, 실제로는 인증에 성공한 상태입니다.

 

쿠키도 정상적으로 추가되어 있음을 알 수 있습니다. (크롬 개발자도구 - Application - Cookies)

 

 

다음 글에서는 로그인에 성공했을 시 페이지에 변화를 주도록 작업을 해보겠습니다.

 

 

인용

 

C#: Blazor Server에 Google OAuth 연동

Google의 서비스를 이용하기 위해 OAuth를 연동하는 법은 많이 나와 있지만.. Blazor Server에 적용하는 법은 자료가 많이 없다. 정답을 찾기보다는 OAuth 매커니즘 자체를 이해하고, Google의 라이브러리

vip00112.tistory.com