handleAuth method
Authenticates a WebSocketContext.
The JWT is refused, as by AngelAuth over HTTP, if its signature is
wrong, if it has expired, if AngelAuth.enforceIp and it was issued to
another IP address, or if it names no user.
Implementation
Future handleAuth(WebSocketAction action, WebSocketContext socket) async {
if (allowAuth == false) {
socket.sendError(
AngelHttpException.forbidden(
message: 'Authentication over WebSockets is disabled.',
),
);
return;
}
if (action.eventName == authenticateAction &&
action.params['query'] is Map &&
action.params['query']['jwt'] is String) {
try {
var auth = socket.request.container!.make<AngelAuth>();
var jwt = action.params['query']['jwt'] as String;
var token = AuthToken.validate(jwt, auth.hmac);
if (auth.enforceIp && socket.request.ip != token.ipAddress) {
throw AngelHttpException.forbidden(
message: 'JWT cannot be accessed from this IP address.',
);
}
if (token.lifeSpan > -1) {
var expiry = token.issuedAt.add(
Duration(milliseconds: token.lifeSpan.toInt()),
);
if (!expiry.isAfter(DateTime.now())) {
throw AngelHttpException.forbidden(message: 'Expired JWT.');
}
}
Object? user = await auth.deserializer(token.userId);
if (user == null) {
throw AngelHttpException.notAuthenticated(
message: 'The user of the JWT does not exist.',
);
}
socket.request
..container!.registerSingleton<AuthToken>(token)
..container!.registerSingleton(user, as: user.runtimeType);
socket._onAuthenticated.add(null);
socket.send(authenticatedEvent, {
'token': token.serialize(auth.hmac),
'data': user,
});
} catch (e, st) {
_log.severe('Authentication failed');
catchError(e, st, socket);
}
} else {
socket.sendError(
AngelHttpException.badRequest(
message: 'No JWT provided for authentication.',
),
);
}
}