Alec Aivazis edited untitled.html  over 8 years ago

Commit id: 274e0aa7ff3e8d79e7667ef344be5ba8aefc46c2

deletions | additions      

       

  • In 
    In  a single page app, all of the decisions about what view/subview to render occurs on the client and does not require a trip back to the server.
  • This server. This  means that the client has to be able to authenticate the currently logged in user and access its data without going back to the server which means it has to be stored locally.
  •  locally. 

      href="http://">JWTs are good because they allow for the client to be responsible for keeping track of the permissions of the currently logged in user.
    • This user. This  removes the need for a session store in most cases which dramatically increases scalability
      • No scalability and there are no  more potential problem of synchronizing the store among processes with separate memory.
  • However  However  JWTs require a secret key to be decrypted which means it can't happen on the frontend with the same key that the server uses, say for its csrf protection
    • protection. A  malicious visiter would be able to download the source code compiled on a few different views and look for similar strings. One of them would be the secret key so its easily brute-forcible.
  • Because brute-forcible.

    Because  of this it's clear that we need to have unencrypted a  way of viewing the local authentication data for use by the application logic
  • Special logic. However, special  care needs to be made to prevent someone interacting with the developers console to be able to change the local authentication data in order to gain access to restricted parts of the code by elevating their permissions
    • Another permissions. This highlights another  reason not to use global variables
    • This variables.  This  is a different type of network vunerability vulnerability  than the traditional three (xss, csrf, and man in the middle) that arises due to the nature of SPAs
      • Previous SPAs. Previous  paradigms did not have this problem because they could authenticate   every GET request and prevent the user from going somewhere they   shouldn't
  • Since shouldn't. Even if one were to have a solution for this (in light of the malicious browser), we would still still authenticate backend endpoints to prevent data from leaking. The client can never be trusted and performing crypto on the browser is a bad idea. However, we need a quick way to authenticate frontend routing logic that is truthworthy.

    Since  we have to at least talk to the server once in order to login in and authenticate the credentials, we can save a copy of the authentication information in a way that prevents it from being easily changed by the console.
  • Closures console. This means we don't have to perform any crypto on the client and can attempt to trust the data that we have stored. So now the problem changes a bit: How do we store the authentication data that we have retrieved?

    Closures  to the rescue!
  • Create rescue! Create  a function that is available globally in the success handler of the xhr request which will scope the value of the data returned by the server in the closure. The global scope of the closure makes the unencrypted authentication data readable outside that request and "safely" in memory in the sense that a malicious user can not modify it. 
    • It's it. 
        • It's  good to note that this request must be accompanied by valid credentials, so even that is secure.
      • If you wanted to add it to some kind of store that was accessible to the developer console (like redux) then we could not prevent them from easily modifying the data. However, hope is not lost. We can let them modify the data so long as we have some way of invalidating it afterwards.
      • In that case, we need some way of comparing it to a known valid state corresponding to the logged in user which we create when the user logs in and verifying that it is the same
        • That known reference would also be wrapped in a closure to prevent the malicious user from setting globally availible data and then changing the value of the comparison variable to match the new data.
      • In most cases, to achieve persistence, an additional request is required when the user logs in which decrypts the JWT. The server would respond with the authentication information which is in turn stored locally. This data is protected by the above algorithm since changing the value of the data used to authenticate invalidates it when comparing to the source of truth.
      • Authenticating the current user for the role admin then looks something like return isEqual(currentAuthInfo, sourceOfTruth) && intersection(auth.roles, targetRoles)).length > 0