Open moogar0880 opened 9 years ago
So, this is what I'm picturing:
Wrap the RouteByMethod
with an authenticate
method for those that need it
authenticate
validates the auth_token header
Resources which need to know which user they're acting upon will use GetUserFromRequest
to exchange the auth token for a user ID
Method names, as always, are negotiable.
Yup, that's pretty much all it is. We'll probably want to flush out the authenticate
decorator before we write it though.
Things will get kind of tricky when we need to convert a username-password combination into an auth token though. Still haven't quite wrapped my head around that yet, but I'm still reading up on auth mechanisms
tl;dr auth is weirdly simple, except for when it isn't
Will it be more than running an auth
endpoint that swaps username and password for an auth token?
Also, after reading this https://codingkilledthecat.wordpress.com/2012/09/04/some-best-practices-for-web-app-authentication/
...I'm thinking it wouldn't really be any harder now to pull PII into a separate table, and have a table like:
Password hash User ID Current Auth token Auth token last seen time .... Maybe more auth token details
And then real name, email, address, ask that stuff lives elsewhere in the PII table. Some questions about salting password hashes, mainly how you can reliably do so.
So, username/passwords are actually more complex than that. You need to hash them before you send the request from the client (no distinguishable credentials get sent on the wire), and then you need a way to reliably unhash them on the server, so you can check the encrypted value against the one in the database before you can validate the users credentials. And that's actually where, eventually, the notion of applications will come into play. One hashing option would be to use a known application key on the client side to hash the provided credentials and then send those out. The other semi-popular solution that I've seen people suggest you hash with is a known timestamp.
As for reliably salting password hashes, I found this to be a pretty informative intro to how password hash salting works: (http://security.stackexchange.com/questions/91447/understanding-salted-password-hashing-using-java) The commenters to do a decent job of expanding on the tutorial that OP originally linked to, which was also a pretty decent read.
And sure, separating password stuff from the user record that they're linked to sounds pretty reasonable
Re: Our earlier conversation, here's an excerpt from the tutorial linked in my above SO post.
To check if a password is correct, we need the salt, so it is usually stored in the user account database along with the hash, or as part of the hash string itself. The salt does not need to be secret. Just by randomizing the hashes, lookup tables, reverse lookup tables, and rainbow tables become ineffective. An attacker won't know in advance what the salt will be, so they can't pre-compute a lookup table or rainbow table. If each user's password is hashed with a different salt, the reverse lookup table attack won't work either.
I think it's probably premature optimization (or maybe just overkill?) to not just store per-user PasswordSalt's in the db
Handling client auth (from our gym talk):
tAPI := ConnectToTorque(url, options)
user := Authenticate(tAPI, username, password)
bw := metrics.NewBodyweight(179.0, "Morning after a highlighter party")
bw.Post(tAPI, user)
tAPI
holds server configuration. It may not be necessary to pass through to calls.
user
holds session state via the auth token. We may want to make some of the User fields private.
Alternatively, you could use the User as a conduit:
user.Post(tAPI, bw)
...maybe. Depends how generic the REST methods are.
Actually, I'm thinking we could take a page from json.Marshaller
. The torque.API
object can provide Post, Get, Put, Delete, Patch
methods with signature:
func Post(u UserAuth, v interface{}) (http.Response, error)
.
Within these calls, the torque.API
can check if v
implements, say, the ClientPOSTer
interface. If so, let v
POST on behalf of v
. Otherwise, handle it generically.
I'm voting that our initial pass at auth uses a stupid access token implementation. It's similar to the auth method other popular Apis (Twitter, Trakt, etc) have implemented for single script and developer use. It will also be easier to throw OAuth in its place once we're mature enough to need something like that.
Current Requirements
auth_token
header with requests that require authFuture Requirements
https://dev.twitter.com/oauth/overview