Objective: Implement Angular authentication with Satellizer. Your goal is to have working sign up and log in functionality.
From the docs:
Satellizer is a simple to use, end-to-end, token-based authentication module for AngularJS with built-in support for Google, Facebook, LinkedIn, Twitter, Instagram, GitHub, Bitbucket, Yahoo, Twitch, Microsoft (Windows Live) OAuth providers, as well as Email and Password sign-in.
-
Fork and clone this repo
-
Once you're in your app directory, run
npm install
to install the requirednode_modules
. -
In one Terminal window, run
mongod
, and in another, runnodemon
. You will see an error about not finding a.env
file. We'll fix that soon. -
Navigate to
localhost:9000
in the browser. You should see an empty page and an angry red error message in the Chrome console. -
BEFORE WRITING ANY CODE, open up
models/user.js
,resources/auth.js
, andserver.js
. Go through these files and look through each code block to see what is already in place for you. -
Open up
views/index.hbs
andpublic/scripts/app.js
, and see what's in there also. -
Add a "dot" file, called
.env
to the root directory. Add this line to the file:
TOKEN_SECRET=yoursupersecrettoken
This is the secret your server will use to encode the JWT token for each user.
- Before hooking up the front-end, test your server routes via Postman:
- Send a
GET
request to/api/me
just going to that route in your browser. You should see the message: "Please make sure your request has an Authorization header." - Send a
POST
request using Postman tolocalhost:9000/auth/signup
with a testemail
andpassword
. You should see a token that was generated by the server. (You are simulating a form submission, so make sure to usex-www-form-urlencoded
and send your data(email and password) in thebody
of the request). - Send a
POST
request tolocalhost:9000/auth/login
with theemail
andpassword
you just used to create a new user. You should again see a token that was generated by the server.
- Now it's time to implement authentication from the client. First, you need to include Satellizer in your Angular app:
- Add the Satellizer CDN to
index.hbs
(TODO #1).<script src="https://cdn.jsdelivr.net/satellizer/0.14.1/satellizer.min.js"></script>
- Add the Satellizer module to your Angular app in
app.js
(TODO #2). - Check that you can navigate between your routes (
/
,/signup
,/login
, and/profile
).
-
Follow the instructions in
public/scripts/app.js
to finish implementingAccount.login()
(TODO #3, #4, #5). You can test this on/login/
with the email and password you used to create a user in setup.TODO #3 Hint
- `console.log(response)` to find the token we're setting.TODO #4 Hint
- How would we set `new_user` to blank? (we do it higher up in Login Controller)TODO #5 Hint
- Inject $location into your controller - Pass the `'/profile'` path to the function in this [$location documentation](https://docs.angularjs.org/api/ng/service/$location#path) -
Click the "Log Out" link to logout (TODO #6) and make sure it redirects to
/login
(TODO #7).return ( $auth .logout() // delete token .then(function() { $auth.removeToken(); self.user = null; }) )TODO #6 Hint:
- Look at the login method above for a pattern to follow (you only need one anonymous function here, no need for `onSuccess` and `onError`). - Check out [this documentation](https://github.com/sahat/satellizer#user-content-authremovetoken) for a method we can use to remove a tokenTODO #7 Hint:
- Inject $location into this controller also - Pass `'/login'` to the `.path` method we used in #5
-
Implement the functionality outlined in
Account.signup()
(TODO #8, #9, #10).TODO #8 Hint
- Use your `login()` function as a pattern - Use the documentation referenced to build out the rest.TODO #9 Hint
- Remember what we did in #4?TODO #10 Hint
- Remember what we did in #5? -
At this point, you should be able to sign up a user, log them in, and view their profile page from the client.
-
Add a
username
field to the Sign Up form, and add theusername
attribute toUser
model (server-side). Sign up a new user with ausername
(TODO #11 in signup.html, #12 in models/user.js).TODO #11 Hint
```html -
On the user profile page, make a form to edit the user's details. The form should initially be hidden, and when the user clicks a button or link to "Edit Profile", the form should show (Hint:
ng-show
) (TODO #13). -
When the user submits the form, it should call a function in the
ProfileCtrl
(Hint:ng-submit
). The function should send an$http.put
request to/api/me
. Verify that this works. (TODO #14)
No more TODOs! You're on your own from here on out!
-
Create a form on the homepage for the user to add a blog-post (that's right - you're turning your Angular app into a microblog). The blog-post form should have input (
title
) and textarea (content
) fields. Hint: Useng-model
. -
Only show the form if there is a
currentUser
logged in. -
Use the
ng-submit
directive to run a function calledcreatePost
when the user submits the form. -
createPost
should make an$http.post
request to/api/posts
(which isn't defined on the server yet!) with thevm.post
object. -
The next step is to implement posts on the server. First, create a Mongoose model
Post
(models/post.js
). -
A user should have many posts, so add an attribute to the
User
model calledposts
that references thePost
model:
/*
* models/user.js
*/
var userSchema = new Schema({
...
posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }]
});
- In
server.js
, define two new API routes:
GET /api/posts
should retrieve all the posts from the database.POST /api/posts
should create a new post that belongs to the current user (Hint: Use theauth.ensureAuthenticated
function in the route to find the current user).
- Refresh
localhost:9000
in the browser. Make sure you have a user logged in, and try to create a new post. Check the Chrome developer tools to make sure it's working.
-
Validate blog-posts! Ensure a user can't submit an empty title or content. (Use both backend AND frontend validations).
-
On the user's profile page, display the number of posts the user has written. Hint: You'll need to add
.populate('posts')
to yourGET /api/me
route inserver.js
. -
On the user profile page, the "Joined" date isn't formatted very nicely. Use Angular's built-in date filter to display the date in this format:
January 25, 2016
.