This article explores user authentication within a MEAN stack application, employing a common architecture: an Angular single-page app interacting with a Node.js, Express.js, and MongoDB-based REST API. We'll cover key aspects of secure user management.
Core Authentication Challenges:
The process necessitates addressing several crucial points:
High-Level Authentication Overview:
Before delving into the code, let's examine the high-level authentication flow:
crypto
module. Passport.js, within Express, implements authentication strategies (specifically, the local strategy for username/password verification).Example Application Structure:
The complete code is available on GitHub. Prerequisites include Node.js, MongoDB, and the Angular CLI.
Angular Application:
The Angular app features four basic pages:
REST API (Node.js, Express.js, MongoDB):
The API includes three core routes:
/api/register
(POST): User registration./api/login
(POST): User login./api/profile/:USERID
(GET): Retrieves user profile details (protected).MongoDB Schema (Mongoose):
A simple user schema in /api/models/users.js
defines the email
, name
, hash
, and salt
fields. The email
field is unique.
var userSchema = new mongoose.Schema({ email: { type: String, unique: true, required: true }, name: { type: String, required: true }, hash: String, salt: String });
Password Hashing and Salting:
The setPassword
and validPassword
methods, leveraging Node.js's crypto
module, handle secure password management without storing passwords directly.
userSchema.methods.setPassword = function(password) { this.salt = crypto.randomBytes(16).toString('hex'); this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha512').toString('hex'); }; userSchema.methods.validPassword = function(password) { var hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha512').toString('hex'); return this.hash === hash; };
JWT Generation:
The generateJwt
method uses the jsonwebtoken
module to create JWTs. Remember to store your secret securely, ideally as an environment variable, not directly in the code.
userSchema.methods.generateJwt = function() { var expiry = new Date(); expiry.setDate(expiry.getDate() + 7); return jwt.sign({ _id: this._id, email: this.email, name: this.name, exp: parseInt(expiry.getTime() / 1000), }, "MY_SECRET"); };
Passport.js Configuration:
Passport.js simplifies authentication in Express. The /api/config/passport.js
file defines the local strategy:
passport.use(new LocalStrategy({ usernameField: 'email' }, function(username, password, done) { User.findOne({ email: username }, function(err, user) { // ... (error handling and password verification logic) ... }); }));
API Endpoints and Authentication:
The /api/routes/index.js
file defines the API routes, including middleware for JWT authentication using express-jwt
:
var auth = jwt({ secret: 'MY_SECRET', userProperty: 'payload' }); router.get('/profile', auth, ctrlProfile.profileRead);
Angular Authentication Service:
An Angular service (authentication.service.ts
) manages JWT storage (localStorage), retrieval, deletion, API calls, login status checks, and user details extraction from the JWT.
Angular Route Protection:
An Angular route guard (auth-guard.service.ts
) protects the /profile
route, ensuring only logged-in users can access it.
Conclusion:
This comprehensive guide details building a secure authentication system in a MEAN stack application. Remember to always prioritize secure password handling and JWT management. The provided example offers a solid foundation for implementing robust user authentication in your own projects.
Frequently Asked Questions (FAQs): (The original FAQs are already quite comprehensive and well-written. I won't repeat them here, as adding them would make this response excessively long.)
The above is the detailed content of User Authentication with the MEAN Stack. For more information, please follow other related articles on the PHP Chinese website!