본문 바로가기
[개발] 이야기/[DotNet] 이야기

blazor server 쿠키인증 로그인 처리 방법 (무조건 됩니다.)- Authorization requires a cascading parameter of type Task<AuthenticationState>에러 해결법도 있어요

by 헤이나우
반응형

blazor로 오면서 인증방법이 많이 까다로워지고 복잡해 져서 로그인처리를 어떻게 해야하나 찾다가 드디어 방법을 찾았습니다.

 

이것저것 많이 해봤지만 모두 실패 했지만 끝내 잘 되는 방법을 찾았습니다.

성공 방법을 정리할겸 정리해 봅니다. 인증처리 관련 더 공부해야 겠다는 생각이 드네요

 

blazor가 httpcontext에 접근하는게 많이 까다로워져서 ms에서 제공하는 인증만 써야하는 느낌이네요 많이 아쉽네요..

 

blazor 쿠키 로그인을 위한 종속성 주입 항목

service.AddHttpContextAccessor();
service.AddScoped<HttpContextAccessor>();
service.AddHttpClient();
service.AddScoped<HttpClient>();

// 쿠키 인증 사용 
service.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();

서비스에 HttpContext를 사용하기 위해 HttpContext종속성을 주입합니다.

그리고 쿠키인증처리를 위한 종속성도 주입합니다.

 

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

그리고 앱에 인증사용을 위한 종속성 주입을 합니다.

 

그리고 인증을 위한 페이지 2개를 만들어 줄건데 해당 페이지는 UI는 아무것도 없고 오로지 인증 처리만 하고 완료되면 다른 페이지로 Redirect를 할 페이지를 만들어 줍니다.

해당 페이지는 .razor페이지가 아니라 .cshtml페이지로 만들어 줘야 합니다.

그래야 httpcontext에 인증을 할 수 있습니다. (귀찮네요)

 

//Login.cshtml
@page "/Auth/Login"
@model MetaMarket.Web.Pages.Auth.LoginModel
@{
}

//Login.cshtml.cs
[AllowAnonymous]
    public class LoginModel : PageModel
    {
        public async Task<IActionResult> OnGetAsync(string email, string password)
        {
            var claims = new List<Claim>
            {
                new(ClaimTypes.Name, email),
                new (ClaimTypes.Role, "User")
            };

            var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

            var authProperties = new AuthenticationProperties
            {
                IsPersistent = true,
                RedirectUri = this.Request.Host.Value
            };

            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), authProperties);
            return LocalRedirect(Url.Content("~/"));
        }
    }

LoginPage 소스 입니다. 다른건 아니고 해당 페이지가 호출되면 claims에 사용자 정보를 만들어 httpcontext에 쿠키로 구워줍니다. 

Logout도 비슷합니다.

//Logout.cshtml
@page "/Auth/Logout"
@model MetaMarket.Web.Pages.Auth.LogoutModel
@{
}

//Logout.cshtml.cs
public class LogoutModel : PageModel
    {
        public async Task<IActionResult> OnGetAsync()
        {
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

            return LocalRedirect(Url.Content("~/"));
        }
    }
반응형

 

 

해당 페이지가 호출되면 HttpContext에서 SignOut을 통해 로그아웃을 하고 메인페이지로 이동합니다. 

 

그럼 이제 로그인, 로그아웃시 저 위의 페이지만 호출해주면 끝납니다. (엄청 쉽네요 ㅠㅠ)

 

//로그인 처리

/*
DB에 접근해서 사용자가 입력한 아이뒤 패스워드가 일치하는지 검증처리

*/
/*
navigation은 
[Inject]
protected NavigationManager navigation { get; set; }
이런식으로 주입된 navigation을 사용합니다.
*/
navigation.NavigateTo($"/Auth/Login?email={Encode(email)}&password={Encode(password)}",true);

주의) 그리고 주의할것이 path를 입력해 주고 두번째 파라미터에 꼭 true를 줍니다 저걸 안주면 해당 페이지를 못찾는 경우가 있더라구요 

 

로그아웃도 동일합니다.

navigation.NavigateTo("/Auth/Logout", true);

 

 

이러면 기본적인 쿠키 로그인, 로그아웃을 잘됩니다. 

 

<AuthorizeView>
					<Authorized>
						<li class="menu_list">@Name()</li>
						<li class="menu_list"><button type="button" @onclick="Logout">로그아웃</button></li>
					</Authorized>
					<NotAuthorized>
						<li class="menu_list"><a href="/Login">로그인</a></li>
					<li class="menu_list"><a href="/Join">회원가입</a></li>
					</NotAuthorized>
				</AuthorizeView>

하지만 blazor에서 AuthorizeView를 사용하면 에러가 나올겁니다.

 

InvalidOperationException: Authorization requires a cascading parameter of type Task<AuthenticationState>. Consider using CascadingAuthenticationState to supply this....어쩌구 저쩌구
 
이 오류는 간단하게 해결 할 수 있습니다.
app.razor페이지에 태그를 CascadingAuthenticationState추가해 줍니다.
<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
            <FocusOnNavigate RouteData="@routeData" Selector="h1" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <p role="alert">Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

이런식으로 넣으면 해결됩니다.!!

그러면 이제 쿠키인증도 사용하고 AuthorizeView를 활용해 인증전후 레이아웃을 분리 할 수 있습니다.!!

 

이제 검증해보죠

인증전 브라우저 쿠키 항목들

인증 후 

.AspNetCore.Cookies가 추가된게 보이네요!!

 

아무쪼록 이글이 도움이 되었으면 좋겠네요 전 몇일동안 삽질했습니다. ㅠㅠ

 

 

 

잠시만! [Hey To Do]앱을 소개합니다. 

Hey To Do앱은 할일앱을 관리하는 심플한 앱입니다.

할일을 등록하면 등록한 [할일]을 [캘린더]와 [해시태그]로 분류하여 관리할 수 있습니다.

 

iOS, Android모두 다운로드 가능합니다.

 

현재 무료 다운로드 가능합니다 

꼭 한번 써보세요!

 

안드로이드 다운로드

https://play.google.com/store/apps/details?id=kr.co.heynow.todocalendar&pli=1

 

iOS 다운로드

https://apps.apple.com/us/app/hey-to-do-calendar-hashtag/id6475393572

 

 

 

iOS, Android모두 다운로드 가능합니다.

 

안드로이드 다운로드

https://play.google.com/store/apps/details?id=kr.co.heynow.todocalendar&pli=1

 

iOS 다운로드

https://apps.apple.com/us/app/hey-to-do-calendar-hashtag/id6475393572

반응형

댓글