Chat Application - Authentication
# Authentication:
Sử dụng passport và jwt để xử lí authentication cho app.
# 1.Install:
$ npm i passport passport-jwt passport-local jsonwebtoken
# 2.Passport authenticate middleware:
Register:
Callback handle:
Nếu model User đã define pre-hook tự động mã hóa password khi save thì không cần set
password = await bcrypt.hash(password, 10);
thủ công nữa.Define các file
usernameField
,passwordField
passport sẽ tự động get giá trị các field trong request body và đưa vào callback các giá trị tương ứng.
// File: auth/auth.js
const passport = require('passport'); const localStrategy = require('passport-local').Strategy; const User = require('../models/user'); const JWTStrategy = require('passport-jwt').Strategy; const ExtractJWT = require('passport-jwt').ExtractJwt; const bcrypt = require('bcrypt');
passport.use( 'register', new localStrategy( { usernameField: 'name', passwordField: 'password' }, async (name, password, done) => { try { password = await bcrypt.hash(password, 10); const user = await User.create({name, password});
return done(null, user);
} catch (error) {
done(error);
}
}
) );
Sử dụng middleware tại router:
```js
// File: routes/auth.js
router.post(
'/register',
[
upload.single('avatar'),
passport.authenticate('register', {session: false})
],
async (req, res, next) => {
if (req.user) {
const user = req.user;
if (req.file) {
user.addAvatar('assets/images/' + req.file.filename);
}
return res.json({
message: 'Register successful',
status: true
});
}
return res.json({
message: 'Register fail',
status: false
});
}
);
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
Sử dụng 2 middleware:
upload avatar: sử dụng multer
passport authenticate register đã define ở trên.
Login:
Callback handle: Tương tự register, login xử lí find và verify user.
passport.use( 'login', new localStrategy( { usernameField: 'name', passwordField: 'password' }, async (name, password, done) => { try { const user = await User.findOne({name}); if (!user) { return done(null, false, {message: 'User not found'}); } const validate = await user.verifyPassword(password); if (!validate) { return done(null, false, {message: 'Password in correct'}); } return done(null, user, {message: 'Logged in Successfully'}); } catch (error) { return done(error); } } ) );
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
28Sử dụng middleware tại router:
router.post( '/login', async (req, res, next) => { passport.authenticate( 'login', async (err, user, info) => { try { if (err) { return next(err); } if (!user) { const error = new Error(info.message); error.status = 401; return next(error); } req.login( user, {session: false}, async (error) => { if (error) return next(error); const body = {_id: user._id, name: user.name}; const token = jwt.sign({user: body}, 'TOKEN_SECRET'); return res.json({token, name: user.name, avatar: user.avatar, _id: user._id}); } ); } catch (error) { return next(error); } } )(req, res, next); } );
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
30
31
32
33
34
35Trường hợp login thành công return token về client và các request sau sẽ kèm theo token này để verify user.
JWT middleware:
Verify token của user get được từ login
passport.use( new JWTStrategy( { secretOrKey: 'TOKEN_SECRET', jwtFromRequest: ExtractJWT.fromUrlQueryParameter('token') }, async (token, done) => { try { return done(null, token.user); } catch (error) { done(error); } } ) );
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15Get token trong request query param
token
, nếu get trong headers bearer thì dùng methodfromAuthHeaderAsBearerToken
(note: nếu dùng bearer token thì authenticate cho socket hiện bị lỗi chưa resolved được).{session: false}
: passport sẽ verify bằng token không dùng session.// File: app.js app.use('/user', passport.authenticate('jwt', {session: false}), userRoute); // File: routes/user.js router.get( '/profile', (req, res, next) => { res.json({ status: true, user: req.user, }) } );
1
2
3
4
5
6
7
8
9
10
11
12
13Socket authentication: detail ở phần sau.
Series:
- Preview (opens new window)
- Mongoose (opens new window)
- Authentication (opens new window)
- SocketIo (opens new window)
- ReactJs (opens new window)
Github: https://github.com/ninhnguyen22/chat_app (opens new window)