Closed dpjanes closed 10 years ago
My apologies for lack of a test case, I haven't quite got my head around that yet
@dpjanes here's a question for you. I've been using /streams/publicKey/action/privateKey
for some routes, but I would like to figure out something else because that leaves the private key in browser history. The same problem exists if we used a query string param, and POSTing doesn't make sense because the user is retrieving data. Any ideas on how to avoid putting that in the URL?
Yes, it's a little bit horrifying. You actually have the right idea code at around line 278 of index.js, where you have the option to pass in the "keys" via HTTP headers, but I don't think it works with the routing rules you have.
Ideally this would just OAuth but that's a rat's nest of work to implement and I'm not so sure how it works without the concept of account.
From a "wider world" point of view the URLs would be identified via the "streamId", and what you are calling keys would be better called "tokens". Operations would be done RESTfully, i.e.
GET /data/:streamId
GET /data/:streamId/latest
GET /data/:streamId/:recordId
POST /data/:streamId
And the user would use a HTTP header with the appropriate token (read or write). Does this make sense? It actually wouldn't take much work to do this.
Also, under this model you have the potential for multiple read and write tokens, which can be removed, expired, etc.. Then rename the deleteKey to manageToken and that handles management functions.
There's cool things you can do with email addresses and "loginless" management, but I'm getting carried away.
From the browser-oriented management, this is all a bit of a nightmare (in terms of using HTTP headers). I don't think there's away to avoid sessions (which again ties into the email address thing).
@dpjanes Yeah, you can't send custom headers using a standard link. It would all have to be done via JS, which isn't the end of the world, it's just not as clean to implement.
OAuth will be part of phant-manager-sparkfun
, which will have sessions and will use sparkfun.com as it's authentication source, but I'd like to keep the option for people to manage streams anonymously.
I couldn't use REST because it was requested that I support pushing data through GET requests because string concatenation is easy for people to understand. Since input, output, and management are all separate modules, it made sense just to make them separate paths while developing the system. There also are no record IDs for logged data.
Keys are going to be renamed in the next major release, and regeneration will be possible.
That's why I would suggest a separate namespace for the REST interface (if it was ever done). For the most part people interact with services through libraries, so it's all cool anyway,
With OAuth - and I have a reasonable amount of experience with this - is all you end up doing is generating a token that you sign requests with anyway!
At the current state of things, I wouldn't sweat exposing stuff in URLs though it's a good plan to plan not to do it.
Ah. That would make more sense if it was using a separate namespace since the stream metadata also needs a REST interface.
This may sound silly, but for now what about something like HTTP Basic Auth w/ a realm set to the public key? I'm pretty sure I could avoid the standard browser auth dialog with a bit of JS. Custom header based auth could also be enabled for those routes (like the other routes that support the Phant-Private-Key
header).
It's been a while since I used this, but it seems like a solid idea and probably not too difficult to implement.
Thinking out loud:
Realm is publicKey Username is publicKey Password is privateKey
So for example the route
/streams/:publicKey/edit/:privateKey
Becomes available at
/streams/:publicKey/edit/
At which point you do http://en.wikipedia.org/wiki/Basic_access_authentication
You can keep the :privateKey routes available for simple programming clients. It's a bit of nuisance to do that special Base64 encoding and supporting non-sophisticated clients is a requirement.
Scratch using the publicKey as the username - that gives the user two things to copy, which is a nightmare.
@dpjanes yeah, I was thinking that the public key would be autofilled by JS in the user name field, and the UI would prompt the user as it does now for the private key before redirect to the secured page. That way I can pre-auth the user with a AJAX request and they will never see the user/pass browser prompt. I'm going to merge this, and the basic auth can be handled in a different branch since it's outside of the scope of this pull request.
1) Is it possible to autofill a username into a browser username field? 2) Are you planning to try to knock this one out (the basic auth) in the near future?
@dpjanes I'm pretty sure I can just create the basic auth header in JS, and send it in a AJAX request to pre-auth the user before redirect, but I haven't tested it yet. I'm going to take a break from writing docs and implement this on a branch today. I'll send you a link to the pull request.