Skip to content
Don Park edited this page Jul 13, 2017 · 1 revision

API v2 auth

Session keys kept in redis. User accounts are kept in rethinkdb.

Goal: keep usefullness of a compromised redis/rethinkdb to a minimum.

incoming rpc 'auth.email' [email,device_id]

  1. creates api key, sent to user in email, not stored.
  2. store hash(api_key+device_id) => {device_id:device_id email:email}
hset session_keys device_key '[123ab,{device_id: "device123", email:"a"}]'

note: no rethink access needed, unvalidated api key creation/session key storage is low-resource/ddos resistant.

incoming rpc 'auth.session' [session_key]

  1. load session_key value
hget session_keys session_key
  1. if session_key not found, abort
  2. if value.user_id exists in db, authenticate.
  3. if value.email exists in db
  4. a) if user owns device_id, session_key to trusted, authenticate
  5. b) if device_id is unique, create device, session_key to trusted, authenticate
  6. if value.email not in db
  7. a) if device_id is unique, create user, create device, session_key to trusted, authenticate

scenarios

  1. new user, new device * rethink users: [] * redis session keys: [] * RPC: api.email [some@guy device123] * email some@guy api_key1 * redis create hash(api_key1+device123) {device_id: device123, email:some@guy} * RPC: api.session [hash(api_key1+device123)] * no existing email in db, create user and device, replace redis value with {device_id: device123, user_id: 1234} * rethink users: [{id:1234, email:some@guy, devices:[device123]}] * redis session keys: [{hash(api_key1+device123): {device_id: device123}}]

  2. existing user, existing device (restore access after app logout) * rethink users: [{id:1234, email:some@guy, devices:[device123]}] * redis session keys: [{hash(api_key1+device123): {device_id: device123}}] * RPC: api.email [some@guy, device123] * email some@guy api_key2 * redis create hash(api_key2+device123) {device_id: device123, email:some@guy} * RPC: api.session [hash(api_key2+device123)] * email exists in db, ensure device_id * rethink users: [{id:1234, email:some@guy, devices:[device123]}] * redis session keys: [{hash(api_key1+device123): {device_id: device123, user_id: 1234}}, {hash(api_key2+device123): {device_id: device123, user_id: 1234}}]

  3. haxor user, api_key known, device_id unknown, same pre-conditions as #2 * RPC: api.session [hash(api_key+device666)] * session_key not found

  4. haxor user, api_key unknown, device_id known * RPC: api.email [hax@or, device123] * email some@guy api_key3 * redis create hash(api_key3+device123) {device_id: device123, email:hax@or} * RPC: api.session [hash(api_key3+device123)] * email does not exist in db, device exists, stop

  5. existing user, reinstalled app (new device id) * rethink users: [{id:1234, email:some@guy, devices:[device123]}] * redis session keys: [{hash(api_key1+device123): {device_id: device123, user_id: 1234}}] * RPC: api.email [some@guy, device456] * email some@guy api_key2 * redis create hash(api_key2+device456) {device_id: device456, email:some@guy} * RPC: api.session [hash(api_key2+device456)] * email exists in db and device_id is unique, create device

Clone this wiki locally