Objectives

1. Microservice Overview

2. Structure architechture

1
2
3
4
5
6
7
8
9
10
11
12
13
14
user-service/
├── controllers/
│   └── auth.controller.js
├── models/
│   └── user.model.js
├── routes/
│   └── auth.routes.js
├── middlewares/
│   └── validateToken.js
├── utils/
│   └── jwt.js
├── .env
├── server.js
├── package.json

2.1. ExpressJS Setup

Install necessary packages:

1
2
npm init -y
npm install express mongoose dotenv jsonwebtoken bcryptjs

Basic Express server setup (server.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const express = require('express');
const mongoose = require('mongoose');
require('dotenv').config();

const app = express();
app.use(express.json());

// Routes
app.use('/api/auth', require('./routes/auth.routes'));

mongoose.connect(process.env.MONGO_URI)
  .then(() => app.listen(process.env.PORT, () => {
    console.log(`User service running on port ${process.env.PORT}`);
  }))
  .catch(err => console.error(err));

2.2. User Schema (Mongoose)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// models/user.model.js
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');

const userSchema = new mongoose.Schema({
  name: String,
  email: { type: String, unique: true },
  password: String,
  role: { type: String, default: 'customer' }
});

userSchema.pre('save', async function(next) {
  if (this.isModified('password')) {
    this.password = await bcrypt.hash(this.password, 10);
  }
  next();
});

module.exports = mongoose.model('User', userSchema);

2.3 Authentication Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// controllers/auth.controller.js
const User = require('../models/user.model');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');

exports.register = async (req, res) => {
  const { name, email, password } = req.body;
  try {
    const user = new User({ name, email, password });
    await user.save();
    res.status(201).json({ message: 'User registered successfully.' });
  } catch (err) {
    res.status(400).json({ error: 'Registration failed.' });
  }
};

exports.login = async (req, res) => {
  const { email, password } = req.body;
  try {
    const user = await User.findOne({ email });
    if (!user || !await bcrypt.compare(password, user.password))
      return res.status(401).json({ error: 'Invalid credentials' });

    const token = jwt.sign({ userId: user._id, role: user.role }, process.env.JWT_SECRET);
    res.json({ token });
  } catch (err) {
    res.status(500).json({ error: 'Login failed.' });
  }
};

2.4. Routes

1
2
3
4
5
6
7
8
// routes/auth.routes.js
const router = require('express').Router();
const { register, login } = require('../controllers/auth.controller');

router.post('/register', register);
router.post('/login', login);

module.exports = router;

2.5. Environment Variables (.env)

PORT=4001
MONGO_URI=mongodb://localhost:27017/user-service
JWT_SECRET=your_jwt_secret

4. API Testing with Postman

Method Endpoint Payload Description
POST /api/auth/register { name, email, password } Register new user
POST /api/auth/login { email, password } Log in and receive token