title: Architecture Design - REST API to support Facebook Login done by Mobile app
body: <p>I am trying to design REST APIs to support various mobile clients (iOS and Android apps). These apps will let user login using facebook login along with our own email authentication. You can refer to the diagram below to understand my design</p>
  
  <p><img src="https://i.stack.imgur.com/ZdUDD.png" alt="Design flow"></p>
  
  <p>There are two levels of authorization take place:</p>
  
  <p>First one is "Client (or App) Authorization" that uses OAuth2. So when user install our app on mobile device, and starts app, then very first thing, app makes "Client (App) Authorization" as shown in above diagram (1st image). And server sends back an long-lived <code>access_token</code> to client to use for all subsequent calls. Here my question are:</p>
  
  <p>Q1) You can see client is sending <code>client_key</code> and <code>client_secret</code> and I am storing them in <code>client_info</code> table. Should this secret be in plain text or it should be in decryt-able format? If I encrypt it, I still need to keep encryption key somewhere in my system. So how it will make it secure? Also in every call, decryption will be an overhead.</p>
  
  <p>Q2) Is it ok to cache <code>access_token</code> for the client in plain text format in redis and use that cache first?</p>
  
  <p>Q3) In order to be extra safe, I am asking clients to send <code>appsecret_proof</code> to make sure the access_token, they are sending belongs to this client only. It uses the same concept as Facebook <a href="https://developers.facebook.com/docs/graph-api/securing-requests#appsecret_proof" rel="noreferrer">https://developers.facebook.com/docs/graph-api/securing-requests#appsecret_proof</a>. And it is <code>hash_hmac('sha256', access_token, client_secret)</code></p>
  
  <p>Q4) We will only have our own 2 mobile app (each for iOS and Android) and not providing third party to use our API to develop other apps. That means, our <code>client_info</code> table will only have two rows one for each type of apps. So is it okay, that in app code, we keep <code>client_key</code> and <code>client_secret</code> hardcoded? If yes, then in future when we have to invalidate and use new secret then how will we achieve replacing those info? </p>
  
  <p>Q5) Since it is our own apps for couple of years, so there would be multiple access_token will get created against same <code>client_key</code> and <code>client_secret</code>. In order to save all of them, is it a good idea to store <code>client_key</code> as key and an <code>array of all access_tokens</code> as value in redis. In future, when we will open our API to third party, then this redis storage design can still scale? </p>
  
  <p>=================</p>
  
  <p>Later on, user decides to perform some actions on my app, for that we need user to login to his account. For that user click on "facebook login". My app gets <code>facebook access_token</code> and fb user's id from facebook and pass those info to API server (as shown in 2nd diagram). API server takes that token and call facebook API to validate its <code>access_token</code>. Once token is validated, server uses some metadata related to that user along with FB access token to generate our own <code>user_access_token</code>, lets say <code>utoken</code>. And pass that <code>utoken</code> back to client to pass back in every subsequent user specific API calls. Here my questions are:</p>
  
  <p>Q1) Is it ok to save that <code>utoken</code> in database, <code>user_token</code> table. Should this <code>utoken</code> be in plain text or it should be in decryt-able format? If I encrypt it, I still need to keep encryption key somewhere in my system. So how it will make it secure? Also in every call, decryption will be an overhead.</p>
  
  <p>Q2) In every user specific API calls, should I call facebook every time to check <code>facebook access_token</code> is still valid? I believe I should not, as that is not going to get anything to me. Please note, Facebook is ONLY used for "facebook login".</p>
  
  <p>Q3) What are the information I should encrypt to generate <code>utoken</code>? I am thinking to have a hash or associative array of user's <code>email</code>, <code>user id</code>, <code>role</code> and <code>facebook token</code> and then serialize that data structure and finally encrypt it. Do you think that would be good enough. I understand its per my requirement, but as a standard or common app, are they good enough? Or is there any best practice?</p>
  
  <p>Q4) Should client store <code>utoken</code> in its cookie/cache? Isn't that scary?</p>
  
  <p>Q5) Please note user may have multiple devices, logged in with same user credential. That means, in user_token table, we would have to store multiple <code>utokens</code> for those logged-in session, while all of them will belong to the same user. Does that sound right?</p>
  
  <p>A design proposal somewhat smiliar to mine <a href="https://stackoverflow.com/questions/12065492/rest-api-for-website-which-uses-facebook-for-authentication">REST API for website which uses Facebook for authentication</a></p>