本文介绍了将脚手架的登录页面合并到剃刀页面中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Blazor和dotnet core 3.1.1创建了一个示例服务器端应用程序,并搭建了登录和注册页面(Identity Scaffold).

I work with Blazor and dotnet core 3.1.1 created a sample Server Side application and scaffolded a login and register page (Identity Scaffold).

现在的问题是我想将cshtml文件的功能合并到给定的剃刀文件中.

Problem is now that I want to merge the functionality of the cshtml files into the given razor files.

是的:我想将第1步(请参见屏幕截图)的功能带到Counter.razor文件(第2步)中.

Exactly: I want to take the functionality of Step 1 (see screenshot) into the Counter.razor file (Step 2).

问题是cshtml将剃刀中未知的属性,类和文件考虑在内文件.

problem is that the cshtml takes properties, classes and files into account that are not known in my razor file.

例如:

  • 公共异步任务OnPostAsync(string returnUrl = null)
  • 公共异步任务OnGetAsync(string returnUrl = null)
  • Login.cshtml.cs继承自PageModel

所有这些以及更多使我无法集成给定授权机制的情况.

All this and more makes me fail the integration of the given authorization mechanism.

有人能给我一个提示,链接到turorial或其他对我的旅程有帮助的东西吗?

Does anyone have a hint, a link to a turorial or something that helps me on my journey?

非常感谢!

   [AllowAnonymous]
public class LoginModel : PageModel
{
    private readonly UserManager<BlazorApp5User> _userManager;
    private readonly SignInManager<BlazorApp5User> _signInManager;
    private readonly ILogger<LoginModel> _logger;

    public LoginModel(SignInManager<BlazorApp5User> signInManager, 
        ILogger<LoginModel> logger,
        UserManager<BlazorApp5User> userManager)
    {
        _userManager = userManager;
        _signInManager = signInManager;
        _logger = logger;
    }

    [BindProperty]
    public InputModel Input { get; set; }

    public IList<AuthenticationScheme> ExternalLogins { get; set; }

    public string ReturnUrl { get; set; }

    [TempData]
    public string ErrorMessage { get; set; }

    public class InputModel
    {
        [Required]
        [EmailAddress]
        public string Email { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        [Display(Name = "Remember me?")]
        public bool RememberMe { get; set; }
    }

    public async Task OnGetAsync(string returnUrl = null)
    {
        if (!string.IsNullOrEmpty(ErrorMessage))
        {
            ModelState.AddModelError(string.Empty, ErrorMessage);
        }

        returnUrl = returnUrl ?? Url.Content("~/");

        // Clear the existing external cookie to ensure a clean login process
        await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

        ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();

        ReturnUrl = returnUrl;
    }

    public async Task<IActionResult> OnPostAsync(string returnUrl = null)
    {
        returnUrl = returnUrl ?? Url.Content("~/");

        if (ModelState.IsValid)
        {
            // This doesn't count login failures towards account lockout
            // To enable password failures to trigger account lockout, set lockoutOnFailure: true
            var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
            if (result.Succeeded)
            {
                _logger.LogInformation("User logged in.");
                return LocalRedirect(returnUrl);
            }
            if (result.RequiresTwoFactor)
            {
                return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
            }
            if (result.IsLockedOut)
            {
                _logger.LogWarning("User account locked out.");
                return RedirectToPage("./Lockout");
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                return Page();
            }
        }

        // If we got this far, something failed, redisplay form
        return Page();
    }
}

推荐答案

@ baer999,这是从Blazor调用登录"页面以验证用户身份的方法.它还提供了用于创建登录"按钮,注销"按钮等的代码.

@baer999, This is how you can call the Login page from Blazor to authenticate a user. It also provides the code to create Login button, Logout button, etc.

执行以下操作:

  1. 在Pages文件夹中创建一个名为RedirectToLogin的组件,该组件使用以下代码将用户重定向到登录"视图:

RedirectToLogin.razor

@inject NavigationManager NavigationManager

@code{
  [Parameter]
  public string ReturnUrl {get; set;}
  protected override  void OnInitialized()
  {
        ReturnUrl = "~/" + ReturnUrl;
        NavigationManager.NavigateTo($"Identity/Account/Login?returnUrl= 
       {ReturnUrl}", forceLoad:true);
  }
}

  • 在要授权的页面上添加Authorize属性,例如Counter或FetchData组件:

    • Add the Authorize attribute to the pages you want to authorize, as for instance, the Counter or FetchData components:

      @attribute [授权]

      @attribute [Authorize]

      在组件顶部添加属性.

      将以下代码替换为App组件中的代码:

      Replace the following code with the code in the App component:

          <CascadingAuthenticationState>
          <Router AppAssembly="@typeof(Program).Assembly">
          <Found Context="routeData">
                  <AuthorizeRouteView RouteData="@routeData" 
                           DefaultLayout="@typeof(MainLayout)">
                      <NotAuthorized>
                         @{
                           var returnUrl = 
                      NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
                      <RedirectToLogin ReturnUrl="@returnUrl"/>
      
                      }
                      </NotAuthorized>
                      <Authorizing>
                          Wait...
                      </Authorizing>
                  </AuthorizeRouteView>
           </Found>
          <NotFound>
                  <LayoutView Layout="@typeof(MainLayout)">
                      <p>Sorry, there's nothing at this address.</p>
                  </LayoutView>
          </NotFound>
       </Router>
      </CascadingAuthenticationState>  
      

      也将如下所示的NavigationManager注入到App组件的顶部:

      Also inject the NavigationManager at the top of the App component like this:

      @inject NavigationManager NavigationManager
      

      要对此进行测试,请在Fetchdata(或计数器",如果您喜欢)组件页面的顶部,为Authorize属性添加@attribute指令,如下所示:@attribute [Authorize]当未经身份验证的用户尝试访问Fetchdata页面时,执行AuthorizeRouteView.NotAuthorized委托属性,并使用参数属性设置为当前url呈现RedirectToLogin组件.

      To test this, at the top of the Fetchdata (or Counter if you like) component page add the @attribute directive for the Authorize attribute, like this: @attribute [Authorize] When an unauthenticated user tries to access the Fetchdata page, the AuthorizeRouteView.NotAuthorized delegate property is executed, and the RedirectToLogin component is rendered with its parameter attribute set to the current url.

      以下添加内容是向您的应用添加登录和注销按钮...

      The following addition is to add a login and logout buttons to your App...

      1. 在共享"文件夹中创建一个名为LoginDisplay.razor的组件,并将以下代码添加到其中:
           <AuthorizeView>
            <Authorized>
              <a href="Identity/Account/Manage">Hello, 
              @context.User.Identity.Name!</a>
              <form method="post" action="Identity/Account/LogOut">
                  <button type="submit" class="nav-link btn btn-link">Log 
              out</button>
              </form>
            </Authorized>
               <NotAuthorized>
                  <a href="Identity/Account/Register">Register</a>
                  <a href="Identity/Account/Login">Log in</a>
               </NotAuthorized>
            </AuthorizeView>
      

      在MainLayout组件中,添加LoginDisplay元素,如下所示:

      In the MainLayout component add the LoginDisplay element as follows:

      <div class="top-row px-4 auth">
          <LoginDisplay />
          <a href="https://docs.microsoft.com/aspnet/" 
               target="_blank">About</a>
      </div>
      

      运行您的应用并测试登录和注销按钮...

      Run your app and test the login and logout button...

      这篇关于将脚手架的登录页面合并到剃刀页面中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-26 02:41