即使登录ASP.NET CORE,我也有一个401未经授权的Angular



我已经在Angular中创建了一个登录名。我可以登录,当我登录时,我会得到一个jwt密钥。我的问题是,当我登录时,我应该能够从我的api中获得客户端列表。我遵循这里的指示https://code-maze.com/authentication-aspnetcore-jwt-2/我不明白为什么当我试图从我的api中获得客户时,我会得到401。

以下是相关的角度文件

我有auth-guard.service.ts

import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { JwtHelperService } from '@auth0/angular-jwt';

@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {

constructor(private router: Router, private jwtHelper: JwtHelperService) {}


canActivate() {
const token = localStorage.getItem("jwt");

if (token && !this.jwtHelper.isTokenExpired(token)) {
return true;
}
this.router.navigate(["login"]);
return false;
}
}

登录组件工作于

@组件({选择器:'应用程序登录',templateUrl:"/login.component.html',styleUrls:['./login.component.css']})导出类LoginComponent{invalidLogin:布尔值;

constructor(private router: Router, private http: HttpClient) { }
login(form: NgForm) {
const credentials = JSON.stringify(form.value);
this.http.post("https://localhost:44363/api/auth/login", credentials, {
headers: new HttpHeaders({
"Content-Type": "application/json"
})
}).subscribe(response => {
const token = (<any>response).token;
localStorage.setItem("jwt", token);
this.invalidLogin = false;
this.router.navigate(["/"]);
}, err => {
this.invalidLogin = true;
});
} 
}

这是我的应用程序模块

export function tokenGetter() {
return localStorage.getItem("jwt");
}

@NgModule({
declarations: [
AppComponent,
NavMenuComponent,
HomeComponent,
CounterComponent,
FetchDataComponent,
LocationManagerComponent,
ClientsComponent,
ClientDetailsComponent,
LoginComponent
],
imports: [
BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
DataTablesModule,
HttpClientModule,
FormsModule,
RouterModule.forRoot([
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: 'counter', component: CounterComponent },
{ path: 'fetch-data', component: FetchDataComponent },
{ path: 'location-manager', component: LocationManagerComponent },
{ path: 'clients', component: ClientsComponent, canActivate: [AuthGuard]  },
{ path: 'clients/:clientId', component: ClientDetailsComponent, canActivate: [AuthGuard] },
{ path: 'login', component: LoginComponent },
]),
BrowserAnimationsModule,
JwtModule.forRoot({
config: {
tokenGetter: tokenGetter,
whitelistedDomains: ["localhost:44363"],
blacklistedRoutes: []
}
})
],
providers: [AuthGuard],
bootstrap: [AppComponent]
})
export class AppModule {}

芬纳利,这是造成我问题的文件。当我尝试从我的api获取客户端时,我在浏览器中得到了401。

@Component({
selector: 'app-clients',
templateUrl: './clients.component.html',
styleUrls: ['./clients.component.css']
})
export class ClientsComponent implements OnInit {
dtOptions: DataTables.Settings = {};
public clients: Client[];
constructor(private http: HttpClient) { }

ngOnInit(): void {
this.dtOptions = {
pagingType: 'full_numbers',
pageLength: 10,
processing: true
};
this.http.get<Client[]>('https://localhost:44363/api/clients', {
headers: new HttpHeaders({
"Content-Type": "application/json"
})
}).subscribe(result => {
this.clients = result;
}, error => {
console.log(error)
});
}
onSubmit(closet: any, drawer: any) {
//get the value by its property
console.log("Closet: " + closet);
console.log("Drawer: " + drawer);
}
}

以下是相关的csharp文件

在我的启动中,我对其进行了配置,以便使用angular,并使用jwt键。

public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("EnableCORS", builder => 
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddAuthentication(opt =>
{
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(opttions =>
{
opttions.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "https://localhost:44363",
ValidAudience = "https://localhost:44363",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@45"))
};
});
services.AddControllersWithViews();

services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddTransient<DatabaseMigrator>();
services.AddDbContext<erp_colombiaDbContext>(options => options.UseMySql(
Configuration.GetConnectionString("DefaultConnection"),
optionsBuilder => optionsBuilder.MigrationsAssembly(typeof(DesignTimeDbContextFactory).Assembly.FullName)));
services.AddDbContext<erp_colombiaDbContext>(options => options.UseMySql(
Configuration.GetConnectionString("DefaultConnection"),
optionsBuilder => optionsBuilder.MigrationsAssembly(typeof(DesignTimeDbContextFactory).Assembly.FullName)));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseCors("EnableCORS");
app.UseStaticFiles();
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}

这是我想从获得客户端列表的控制器

// GET api/clients
[HttpGet]
[Authorize]
public IEnumerable<ClientViewModel> Get()
{
ClientViewModel clientViewModel;
List<ClientViewModel> listClientViewModels = new List<ClientViewModel>();
var clients = Task.Run(async () => await _clientService.GetAllClients()).Result;
foreach (var client in clients) 
{
clientViewModel = new ClientViewModel();
clientViewModel.ClientId = client.ClientId;
clientViewModel.Active = client.Active;
clientViewModel.Address = client.Address;
clientViewModel.City = client.City;
clientViewModel.ClienteName = client.ClienteName;
clientViewModel.ComercialEmployeeId = client.ComercialEmployeeId;
clientViewModel.Confirmed = client.Confirmed;
clientViewModel.CountryId = client.CountryId;
clientViewModel.CreationDate = client.CreationDate;
clientViewModel.DANE = client.DANE;
clientViewModel.Department = client.Department;
clientViewModel.ElectronicBillingEmail = client.ElectronicBillingEmail;
clientViewModel.Eliminated = client.Eliminated;
clientViewModel.NIT = client.NIT;
clientViewModel.PostalCode = client.PostalCode;
clientViewModel.Phone = client.Phone;
listClientViewModels.Add(clientViewModel);
}
return listClientViewModels;
}

如果我没有错的话,你得到的是401,因为你的请求不是Authorized

因此,您可以将Authorization标头添加到您的请求中,如:

headers: new HttpHeaders({
"Authorization": `Bearer ${localStorage.getItem("jwt")}`,
"Content-Type": "application/json"
})

但我强烈建议使用Interceptor,它将对每个请求应用Authorization token(一次定义,无需复制代码\标头等(

@Injectable()
export class ApplyJWTTokenInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const idToken = localStorage.getItem("jwt");
if (idToken) {
const authClonedRequest = req.clone({
headers: req.headers
.set('Authorization', `Bearer ${idToken}`)
});
return next.handle(authClonedRequest);
}
else {
return next.handle(req);
}
}
}

建议检查:

  1. HTTPInterceptor
  2. 拦截请求和响应
  3. 工作演示

相关内容

最新更新