Comments (7)
Thanks for filing this!
We haven't thought about auth much yet. For now you can, of course, add the auth information as an argument (though I realize it's less convenient).
I think having some kind of user metadata like gRPC seems good, as does having some kind of BeforeMiddleware (and probably After as well). I spoke with @tikue a bit and his concern is that we don't clutter the existing API if people don't care about this kind of thing. That seems easy to satisfy though.
But then it's not pure RPC anymore?
What do you mean by this?
from tarpc.
But then it's not pure RPC anymore?
What do you mean by this?
I mean, if middlewares come into the picture, there is no 1-to-1 correspondence between caller and callee like with normal function calls.
I've been thinking about middlewares some more and came to the conclusion that it would probably complicate things too much.
If a BeforeMiddleware can reject the call (like for auth), it would have to be reflected in the function's return type. If it can only modify function args, it's not that useful...
The big advantage of RPC vs a normal JSON/REST API is type safety between server and client, so it's probably better to reflect the possible failure modes in the return type of the functions explicitly.
But metadata like in gRPC could still be useful for things like auth.
from tarpc.
It could be reflected in the type signature like this:
// Given this service:
service! {
rpc foo() -> Foo | Bar;
rpc baz() -> Baz | Error;
}
// ...this is generated:
trait Before {
type BeforeError: Into<Bar> + Into<Error>;
/// Returning Ok continues to the rpc handler.
/// Returning Err propagates to the user by converting to the appropriate error type.
fn before(&self) -> Result<(), Self::BeforeError>;
}
from tarpc.
I had considered this idea too, especially for authentication, but I decided to let types to do the work for me. I'm currently doing something like this:
service! {
rpc baz(untrusted_baz: UntrustedBaz) -> Baz | Error;
}
fn baz(&self, untrusted_baz: UntrustedBaz) -> Result<Baz, Error> {
let baz: Baz = untrusted_baz.try_into()?; // do your authentication/validation etc. here
// do whatever you need to do with baz now
}
from tarpc.
That's a neat pattern! I've got a branch on my personal repo that has experimental support for task-local contexts. It seems pretty cool, but requiring being on-task is kind of an awkward limitation presently.
I honestly don't know which I prefer. I do agree that providing credentials explicitly to each request feels boilerplatey. But I also worry about any kind of local data because it's always error prone, e.g. when spawning new tasks or threads you need to manually propagate the context.
from tarpc.
I'm pretty sure this will be a lot easier to accomplish now that services are essentially just FnOnce(Request) -> Response + Clone
.
I'm imagining something like...(this is a strawman example, but hopefully you can get the idea)
/// Returns a serve fn that only allows authenticated users to be served.
fn serve_authenticated<Req, Resp>(
allowed_users: Arc<HashSet<String>>,
serve: impl FnOnce(Req) -> impl Future<Output = Result<Resp, ServerError>> + Clone,
) -> impl FnOnce(RequestWithMetadata<Req>) -> impl Future<Output = Result<Resp, ServerError>> + Clone {
async move |request| {
if allowed_users.contains(&request.metadata.user) {
await!(serve(request.request))
} else {
Err(UnauthenticatedError)
}
}
}
from tarpc.
Another option (for auth, specifically) is to plug it in at the transport layer, so that it's completely transparent to the user. Effectively, it'd transform a Transport<RequestWithMetadata<Request>, Response>
to a Transport<Request, Response>
by doing whatever it needs to with the metadata, and then passing along only the request body.
from tarpc.
Related Issues (20)
- Removing the dependency on tokio HOT 3
- No error details when exceeding of LengthDelimitedCodec's max frame length HOT 6
- use qualified paths for all macro generated signatures HOT 1
- Why is it called tarpc? HOT 2
- How to save transport context? HOT 24
- Multi-client requests HOT 2
- Bidirectional RPC HOT 3
- Cross Platform Procedure Call HOT 2
- [FEATURE REQUEST] Stream responses HOT 4
- QUESTION: how to get tcp server features for custom transport? HOT 1
- Consider making tracing optional HOT 8
- Bubble up server side transport errors to the client HOT 5
- Design problem, how to call other structs method ?
- Server-side span with client’s span as parent HOT 3
- Recommended way for connection pooling? HOT 4
- Support for Async Fn in Trait? HOT 3
- Generic type parameters HOT 4
- On client's read errors quick subsequent requests may wait for response indefinitely HOT 9
- Adding client ID to identify clients (and retrieve specific context)? HOT 2
- Associated data with client
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tarpc.