Pregunta

I'm relatively new to web development, so I apologize if this question is a bit basic. I've been doing research for the past 3 hours on how to solve this issue that I think is very common. However, because I am not an expert, I am unable to tell whether my understanding is correct.

In short, I am developing a simple web app in AngularJS, and using Google App Engine as my data store. I flirted with the idea of using Firebase as my data store, but I am strongly attached to certain Google App Engine features (mainly ability to query).

In essence my site will have users. Users can create projects. Users can grant other users access to their projects. For a given project (with a given projectID), only certain users should be able to access it. Thus, an http.$get request to /rest/projects/[projectID] should only be able to be accessed by users with that projectID in their projects.

Conceptually, from what I understand from my reading, the ideal scenario is if I have a user login system in Google App Engine that upon logging in, will send back a session token OR cookie. Then, whenever I make a request to the server from AngularJS, I will send this token/cookie through the HTTP headers. Then, my server can parse this cookie to understand what user it is, and from that figure out if the user should have access to a particular project.

It seems that Google App Engine doesn't have an authentication system that allows for emails/passwords that are custom; in other words, I don't want to use App Engine's option of authenticating using a user's google account. I want users to be able to sign up using whatever email they have and whatever password they want.

It turns out that Firebase has a SimpleLogin module that I can easily implement. However, the authentication token that I receive from Firebase can't really be used to implement security on Google App Engine right?

Ultimately my question boils down to: Let's say I use Firebase's SimpleLogin to authenticate users and use the authentication token from FireBase's SimpleLogin to store whether a user is logged in. I can't use that token to enforce security to my data store (Google App Engine), right?

¿Fue útil?

Solución

This is something I wrote few days ago, also for GAE+AngularJS. Have a look maybe you could adopt it for your scenario.

Basic idea is:

1) When user logs in you generate a session token from user data, time and project data and send that as cookie. ( I'm using simple encoding at the moment. If you need look into some heavier encription).

2) You combine that cookie with your master key and save that in server session.

3) On following requests, you check if cookie matches header and if (when you combine them with master key) they match token you stored in session.

4) If they don't match, deny access

Full disclosure: I'm not any kind of security or optimization expert, so I don't know if this is good solution or not, it. This is something I deduced from various online sources, and haven't tested it yet, so use it with caution (;

class Handler( webapp2.RequestHandler ):
  @property
  def verified( self ):
    if not self.user: _verified = False
    else:
      _verified = False
      _cookie = self.request.cookies.get( 'XSRF-TOKEN' )
      _header = self.request.headers.get( 'X-XSRF-TOKEN' )

      if _header == _cookie and self.token == hashlib.sha1(
                  str( _header ) + '::' + MASTER_KEY ).hexdigest( ): _verified = True
    return _verified

  @webapp2.cached_property
  def token( self ):
    def generate_session_token( value ):
      user_hash = hashlib.sha1( value ).hexdigest( )
      time_hash = hashlib.sha1( '%s' % time.mktime( datetime.now( ).timetuple( ) ) ).hexdigest( )
      app_hash = hashlib.sha1( PROJECT ).hexdigest( )
      return hashlib.sha1( app_hash + '::' + user_hash + '::' + time_hash ).hexdigest( )

    if 'XSRF-TOKEN' not in self.session:
      _token = generate_session_token( self.user )
      self.session.update( { 'XSRF-TOKEN': hashlib.sha1( _token + '::' + MASTER_KEY ).hexdigest( ) } )
    return self.session.get( 'XSRF-TOKEN' )

  def login_callback( self, provider ):
    if provider == 'admin':
      self.response.set_cookie( 'XSRF-TOKEN', self.token )
      self.redirect( '/' )

  def get(self):
    if not self.verified: self.error( 401 )
    else:
      self.displayProject()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top