Auth Data Flow

WORKSHOP GOALS 

1 - authenticate users: make users login locally or through a third party

2 - authorize users for certain resources 

3 - understand the codebase well enough to accomplish these things 

 

goal: to go through the workshop in the most intuitive way 

goal: to understand the sessions and passport configurations necessary to keep a user logged in 

 

 

 

 

STARTING POINT: 

 

1. already have a signup controller and login controller that use auth factory methods to post data to the db 

 

2. I've already set up the auth router to receive these requests 

 

3. so now I have to do sessions 

 

 

 

 

 

 

 GOAL: server-side sessions to persist user data between a server and client across multiple requests (keep user logged in);

1. each session is particular to a given client—even across requests

2. a session will be a JavaScript object living in the runtime of our server.

3. This session object will contain data about a particular client—something we have so far been unable to do.

4. Sessions have no inherent understanding of "users"—they are simply a means to persist data across many different request/response cycles between the same server and client.

In server/app/Index.js: This middleware will give you access to a req.session object for any middleware that is downstream of it. Editing this object will edit it for all subsequent requests from the same client.

 

 

 

 

and I can use the session info anywhere after the requestState stuff so lets put it right below it 

so now i'll have a session object any time a user makes a request for the index html page 

1.  a session will be a JavaScript object living in the runtime of our server.

2. this session object lives in a larger sessions hash 

3. Anytime we restart our app, all of the user sessions are lost. 

In server/app/Index.js:

the secret encrypts / hash the session id so that it isn't guessable 

 

 

 

we have access to req.session in any middleware the is downstream of this hashing middleware, including our auth router. so now we can use sessions in login and signup 

add user to session in auth login controller:

and this has to be session.userId because id is protected on the session obj (a read only property) because it is the primary key so we can't assign to it 

 

 

in server/app/index.js:

we can add this to the signup controller in our auth router as well 

 

by adding the user id to the session object of a user that just signed up, we're essentially logging them in 

ADD LOGOUT functionality to factory and auth router 

 

add isLoggedIn functionality to navbar directive

so now we can create functions that will help us manage state for the navbar : we need to create this getCurrentUser function 

 

 

add getCurrentUser to Auth factory 

 

 

modify navbar html

 

 

 

so now when I log in, only logout should appear 

 

but what happens if I refresh? the currentUser disappears so I see the wrong buttons again 

 

so I need to find a way to manage the currentUser state even when a user logs in 

 

 

 

add refreshCurrentUser to the auth factory 

 

app.run in main.js

run blocks: this will run on refresh every time. so on refresh we re-retrieve the user and set it to currentUser so we can maintain that state

 

in a config step you have access to providers and providers are slightly different from factories, they're like pre-built factories (it's like saying before you boot this app, change this factory just a little bit ; so they're configurable factories )

 

in a run state, we can't configure factories anymore

add user/me route to user controller 

(uses router.params)

so now refresh should work 

PART 2: now for google oauth: we need to make the google button work 

 

1. when you click the button we want to send a request to google, so we need to do a reload so that we hit this route on the backend 

and then route that request to a script that will handle google oauth by mounting it in our auth router. so add to our auth router 

PART 2:

so now we create a google oauth script 

so without worrying about the config just yet, we know from the lecture that we'll need 2 routes: 

1) a route that handles the request for logging into google (when a user clicks the sign in via google button) 

2) and a callback route that google will use to redirect that user once that user has authenticated 

the whole point of the authenticate('google') is to tell passport to use the google strategy we are about to configure 

- done function passes our data on to passport so that it can associate the user document with a session 

- configuring a new google strategy for passport to use

- so the done function is so that we can tell passport when we're done doing what we want to do 

- clientSecret is the password 



find the user or create it 

so that passport can associate the user with the session 

using methods provided by passport-session:

1. passport initialize: adds methods to the req object that will be accessible in all the middleware downstream of it 

2. the passport.session: will talk to other session middleware and use req.session for us

 

 

 

 

so associateWithSession won't quite work yet. we still need to do some stuff in app/index for this to work.  

passport serializeUser: receives the user doc and done. we need to tell it what data to associate a user with a session: the id of the user.

associateWithSession from googleOauth triggers passports serializeUserFunction

 

 

 

 

deserializeUser needs to look up the user with the info we passed to it in serializeUser so that it can attach that user to the req object

the req.user object that passport gives us

we can now inspect this object 

does anyone have an idea about what middleware is responsible for providing us with this req.user object ?

attachThisToTheSessionSomehow runs once when the user logs in via passport

associateWithSession from googleOauth triggers passports serializeUserFunction

to which we passed the user document that our anonymous fn has access to  

but neither of these is express middleware. and the question is: what express middleware is responsible for providing us with the req.user object?

1. passport.initialize: gives us method on the req object

2. passport.session: looks up the deserializeUser function and the piece of info associated with the session and say req.user equals the object looked up 

 

so now we don't have to work with the session directly anymore. because passport handles that for us

 

so now let's figure out how to only user passport for managing sessions because we still have req.session.userId in our code 

 

so we do this now 

 

 

 

so we do this now 

 

 

 

now change the get me router to use req.user 

 

 

 

Performance considerations: 

we should put the passport initialize and session middleware beneath the statics middlware to reduce num of requests 

 

 

Overview: what's the order of operations

 

1. clicking sign in with google (clicking this link takes them to auth/google which, because of code we have in the  main.js, reloads the entire page, which triggers a backend request to /auth/google 

2. and we handle the /auth/google request  in the google oauth router. (router.get('/', passport.authenticate...)

3. passport.authenticate redirects us to google login page 

4. user signs in to google 

5. signing in triggers a request to google and google redirects us to the callback url --- /auth/google/callback because that's what we told it to do 

6. we handle this in the router.get('/callback'...) middleware which triggers our whenDataComeBackFromGoogle callback which looks up the user or creates the user 

7. then we call associateWithSession callback which triggers the serialization 

8. the serialization takes care of the associate and then the successRedirect triggers - makes a request for /stories and the server serves up index.html 

9. app.run makes a request for current user 

10. for all subsequent request, deserializeUser runs. every time we make a request, we attach the user document to the request object 

Auth Data Flow

By ayana28

Auth Data Flow

  • 1,635