You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular与C#登录集成后重定向异常问题求助

问题描述

我正在做一个POC,用C#保护我的Angular应用。我在C#中创建了一个登录页面(运行在https://localhost:7139/account/login),现在想要保护运行在https://localhost:4200的Angular应用,防止未授权用户访问。目前我硬编码了登录凭据,并尝试通过在Angular中创建resolver来实现保护。

现有代码

C# 登录页面(login.cshtml)

<div class="container border" style="padding:20px">
    <form method="post">
        <div class="text-danger" asp-validation-summary="ModelOnly"></div>
        <div class="form-group row">
            <div class="col-3">
                <label asp-for="Credential.Username"></label>
            </div>
            <div class="col-5">
                <input type="text" asp-for="Credential.Username" class="form-control" />
            </div>
            <div class="text-danger" asp-validation-for="Credential.Username"></div>
        </div><br />
        <div class="form-group row">
            <div class="col-3">
                <label asp-for="Credential.Password"></label>
            </div>
            <div class="col-5">
                <input type="password" asp-for="Credential.Password" class="form-control" />
            </div>
            <div class="text-danger" asp-validation-for="Credential.Password"></div>
        </div>

        <div class="form-group row">
            <div class="col-3">
                <input type="submit" class="btn btn-primary" value="Login" />
            </div>
        </div>
    </form>
</div>

C# 控制器代码

using Identity.Pages.Account;
using Microsoft.AspNetCore.Mvc;

namespace Identity.Controller
{
    [ApiController]
    public class LoginController : ControllerBase
    {
        [HttpPost]
        [Route("account/login")]
        public async Task<IActionResult> OnPostAsync([FromForm] Credential credential)
        {
            if (credential.Username == "badruddin" && credential.Password == "khan@123")
            {
                return Redirect("http://localhost:4200/");
            }
            else
            {
                return NotFound("User Not Found");
            }
        }
    }
}

Angular service.service.ts代码

export class serviceService {
  
   check = true;
  constructor() { }

    loginUrl(): any {
      if(this.check == true){
      this.check = false;
      return window.location.href = 'https://localhost:7139/account/login';
      }
    }
}

Angular resolver代码

export class ResolveResolver implements Resolve<boolean> {

  constructor(private service:MyserviceService){}
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
  
    this.service.loginUrl()
    return of(true);
    
  }
}

Angular app-routing.ts代码

const routes: Routes = [
  {path:'', component:AppComponent, pathMatch:'full', resolve: {redirection: ResolveResolver} }
];

当前问题

打开Angular应用时会重定向到C#登录页,输入正确凭据点击登录后,会短暂跳转到Angular应用,随后自动重定向回登录页。我希望验证通过后能停留在Angular应用中,目前未使用Cookie或JWT token。


解决方案

问题核心是登录成功后没有持久化用户已登录状态,Angular的resolver每次加载路由时都会触发检查,因为无状态标记,所以再次重定向到登录页。以下是分步解决方法:

1. 修改C#登录控制器,传递登录状态标记

登录成功后,给Angular的重定向URL添加loggedIn=true参数,明确告知用户已登录:

[HttpPost]
[Route("account/login")]
public async Task<IActionResult> OnPostAsync([FromForm] Credential credential)
{
    if (credential.Username == "badruddin" && credential.Password == "khan@123")
    {
        // 重定向时携带登录状态参数
        return Redirect("http://localhost:4200/?loggedIn=true");
    }
    else
    {
        return NotFound("User Not Found");
    }
}

2. 改造Angular服务,持久化登录状态

使用localStorage保存登录状态(POC场景足够,生产环境建议用Cookie或JWT):

export class serviceService {
  constructor() { }

  // 检查是否已登录
  isLoggedIn(): boolean {
    return localStorage.getItem('isLoggedIn') === 'true';
  }

  // 设置登录状态
  setLoggedIn(status: boolean): void {
    localStorage.setItem('isLoggedIn', status.toString());
  }

  loginUrl(): void {
    if (!this.isLoggedIn()) {
      window.location.href = 'https://localhost:7139/account/login';
    }
  }
}

3. 修改Resolver,根据状态决定是否重定向

Resolver中先检查路由参数和本地存储状态,仅未登录时才跳转:

export class ResolveResolver implements Resolve<boolean> {
  constructor(private service: serviceService){}
  
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    // 读取路由参数中的登录标记,设置本地存储
    const loggedInParam = route.queryParamMap.get('loggedIn');
    if (loggedInParam === 'true') {
      this.service.setLoggedIn(true);
    }

    // 未登录时跳转到登录页,否则正常加载路由
    if (!this.service.isLoggedIn()) {
      this.service.loginUrl();
    }
    return of(true);
  }
}

4. 可选:添加登出功能(方便测试)

在Angular服务中添加登出方法,清除本地存储状态:

// 在serviceService中新增
logout(): void {
  localStorage.removeItem('isLoggedIn');
  window.location.href = 'https://localhost:7139/account/login';
}

问题根源说明

之前的check变量是服务实例变量,页面刷新时Angular会重新创建服务实例,check重置为true,导致Resolver再次触发重定向。用localStorage可以跨页面刷新持久化状态,解决循环重定向问题。

内容的提问来源于stack exchange,提问作者Badruddin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 01:00:59