SignalR ist eine Bibliothek von Microsoft, die es ermöglicht, in Echtzeit Daten zwischen einem Server und Clients auszutauschen. Wenn man SignalR in einer Angular-Anwendung verwendet, kann es notwendig sein, Authentifizierungsmechanismen zu implementieren, um sicherzustellen, dass nur autorisierte Benutzer Zugriff auf die SignalR-Verbindungen haben. In diesem Artikel zeige ich, wie man SignalR in Angular mit JWT-Token-Authentifizierung integriert.
Voraussetzungen
- Angular (Version 15 oder höher)
- ASP.NET Core (für die Backend-API)
- Node.js und npm (für Angular CLI)
- Kenntnisse in Angular, TypeScript, C#, und ASP.NET Core
1. Backend-Setup (ASP.NET Core)
Zuerst richten wir das Backend mit ASP.NET Core ein. Es ist wichtig, die Authentifizierung mit JWT-Token zu konfigurieren, da Angular diese Tokens für die Verbindung zu SignalR verwenden wird.
1.1. SignalR Hub erstellen
Erstellen Sie eine neue Hub-Klasse, z.B. ChatHub.cs.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
[Authorize] // Autorisiert nur authentifizierte Benutzer
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
1.2. JWT-Authentifizierung konfigurieren
In der Program.cs (oder Startup.cs für ältere Versionen) konfigurieren wir die JWT-Authentifizierung.
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// JWT-Authentifizierung konfigurieren
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "yourissuer",
ValidAudience = "youraudience",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("yoursecretkey"))
};
// SignalR spezifische Konfiguration
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
// Token aus der Abfragezeichenfolge extrahieren
var accessToken = context.Request.Query["access_token"];
// Überprüfen, ob der Hub-Aufruf gemacht wird
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/chathub"))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
app.UseAuthentication();
app.UseAuthorization();
app.MapHub<ChatHub>("/chathub");
app.Run();
1.3. Angular-Client vorbereiten
Installieren Sie die notwendigen Pakete:
npm install @microsoft/signalr
2. Angular Client-Setup
Nun richten wir den Angular-Client ein.
2.1. SignalR-Service erstellen
Erstellen Sie einen neuen Service signalr.service.ts.
import { Injectable } from '@angular/core';
import * as signalR from '@microsoft/signalr';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class SignalRService {
private hubConnection: signalR.HubConnection;
public messageReceived = new BehaviorSubject<{ user: string, message: string } | null>(null);
constructor(private http: HttpClient) {}
public startConnection(token: string): void {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl('https://localhost:5001/chathub', {
accessTokenFactory: () => token,
})
.withAutomaticReconnect()
.build();
this.hubConnection
.start()
.then(() => console.log('SignalR-Verbindung gestartet'))
.catch((err) => console.error('Fehler beim Starten der SignalR-Verbindung:', err));
this.hubConnection.on('ReceiveMessage', (user: string, message: string) => {
this.messageReceived.next({ user, message });
});
}
public sendMessage(user: string, message: string): void {
this.hubConnection
.invoke('SendMessage', user, message)
.catch((err) => console.error('Fehler beim Senden der Nachricht:', err));
}
}
2.2. Nutzung des Services in einer Komponente
Erstellen Sie eine Komponente chat.component.ts.
import { Component, OnInit } from '@angular/core';
import { SignalRService } from './signalr.service';
import { AuthService } from './auth.service';
@Component({
selector: 'app-chat',
template: `
<div>
<h2>Chat</h2>
<div *ngFor="let msg of messages">
<strong>{{ msg.user }}:</strong> {{ msg.message }}
</div>
<input [(ngModel)]="user" placeholder="Benutzername" />
<input [(ngModel)]="message" placeholder="Nachricht" />
<button (click)="sendMessage()">Senden</button>
</div>
`,
})
export class ChatComponent implements OnInit {
user = '';
message = '';
messages: { user: string; message: string }[] = [];
constructor(
private signalRService: SignalRService,
private authService: AuthService
) {}
ngOnInit(): void {
const token = this.authService.getToken(); // Token vom AuthService holen
this.signalRService.startConnection(token);
this.signalRService.messageReceived.subscribe((msg) => {
if (msg) this.messages.push(msg);
});
}
sendMessage(): void {
this.signalRService.sendMessage(this.user, this.message);
this.message = '';
}
}
2.3. AuthService zur Verwaltung des Tokens
Erstellen Sie den auth.service.ts, um den JWT-Token zu handhaben.
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class AuthService {
private tokenKey = 'authToken';
constructor() {}
setToken(token: string): void {
localStorage.setItem(this.tokenKey, token);
}
getToken(): string {
return localStorage.getItem(this.tokenKey) ?? '';
}
}
3. Fazit
Mit dieser Implementierung haben wir eine einfache Möglichkeit geschaffen, SignalR in einer Angular-Anwendung mit JWT-Authentifizierung zu verwenden. Dabei sind die Hauptpunkte:
- Authentifizierung: Sicherstellen, dass nur autorisierte Benutzer mit dem SignalR-Hub kommunizieren können.
- JWT-Token: Das Token wird in der access_token-Abfragezeichenfolge übergeben und vom Server validiert.
- Echtzeit-Kommunikation: Der Angular-Client empfängt Nachrichten in Echtzeit und zeigt sie an. Mit dieser Methode kann SignalR sicher in Angular-Anwendungen integriert werden, um eine Authentifizierung und Autorisierung durchzuführen.