Skip to content

Commit 6002ba5

Browse files
committed
Improve the user auth and token verification
1 parent 4ea4953 commit 6002ba5

File tree

4 files changed

+58
-32
lines changed

4 files changed

+58
-32
lines changed

.env.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
PORT=7770
22
ALLOW_ORIGIN=http://localhost:7771
33
JWT_SECRET=jwtsecretcode
4+
HASH=356a192b7913b04c54574d18c28d46e6395428ab.da4b9237bacccdf19c0760cab7aec4a8359010b0.77de68daecd823babbb58edb1c8e14d7106e83bb.1b6453892473a467d07372d45eb05abc2031647a.ac3478d69a3c81fa62e60f5c3696165a4e5e6ac4
45
POSTGRES_PORT=5432
56
POSTGRES_DB=express_api_dev
67
POSTGRES_USER=express_api_user

README.md

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,17 @@ Copy `.env.dist` to `.env` and change the values of the environment variables if
2222
PORT=7770
2323
ALLOW_ORIGIN=http://localhost:7771
2424
JWT_SECRET=jwtsecretcode
25+
HASH=sha1hash1.sha1hash2.sha1hash3
2526
POSTGRES_PORT=5432
2627
POSTGRES_DB=express_api_dev
2728
POSTGRES_USER=express_api_user
2829
POSTGRES_PASSWORD=root
2930
```
3031

32+
NOTE: Generate random hashes and concatenate the hashes with “.”.
33+
The same hashes should also be used in the React client app.
34+
The more hashes, the better.
35+
3136
Then run the following commands:
3237

3338
```
@@ -87,33 +92,33 @@ To manage separate Docker instance for API, open another terminal console and ru
8792

8893
### Docker
8994

90-
| Command | Description |
91-
|----------------------------------------|--------------------------------------------------------------------|
92-
| `./bin/install` | Build the Docker containers, initialise database and start the app |
93-
| `./bin/reinstall` | Re-build containers, re-initialise database and start the app |
94-
| `./bin/start` | Start all the services (API and database) |
95-
| `./bin/stop` | Stop all the services |
96-
| `./bin/console <container ID or Name>` | Access the terminal console of the API container |
95+
| Command | Description |
96+
|--------------------------------------|--------------------------------------------------------------------|
97+
| `bin/install` | Build the Docker containers, initialise database and start the app |
98+
| `bin/reinstall` | Re-build containers, re-initialise database and start the app |
99+
| `bin/start` | Start all the services (API and database) |
100+
| `bin/stop` | Stop all the services |
101+
| `bin/console <container ID or Name>` | Access the terminal console of the API container |
97102

98103
### Database
99104

100105
**Local**
101106

102-
| Command | Description |
103-
|---------------------------------------|------------------------------------------------------------|
104-
| `./bin/pg/local/start` | Start the PostgreSQL server (for Mac users only) |
105-
| `./bin/pg/local/resetdb` | Drop and re-initialise database |
106-
| `./bin/pg/local/migrate` | Run new schema migration |
107-
| `./bin/pg/local/migrateundo` | Revert the recent schema migration |
108-
| `./bin/pg/local/seed <seed file>` | Run specific data seed file with or without .js extension |
109-
| `./bin/pg/local/seedundo <seed file>` | Revert the seed of specific data seed file |
110-
| `./bin/pg/local/psql` | Access the database console |
107+
| Command | Description |
108+
|-------------------------------------|------------------------------------------------------------|
109+
| `bin/pg/local/start` | Start the PostgreSQL server (for Mac users only) |
110+
| `bin/pg/local/resetdb` | Drop and re-initialise database |
111+
| `bin/pg/local/migrate` | Run new schema migration |
112+
| `bin/pg/local/migrateundo` | Revert the recent schema migration |
113+
| `bin/pg/local/seed <seed file>` | Run specific data seed file with or without .js extension |
114+
| `bin/pg/local/seedundo <seed file>` | Revert the seed of specific data seed file |
115+
| `bin/pg/local/psql` | Access the database console |
111116

112117
**Docker**
113118

114119
- To run the commands for Docker database service, simply remove the `local` from the command
115120
- The `start` command works only in local machine
116-
- Used `./bin/pg/psql <database container ID or Name>` to access the database console
121+
- Used `bin/pg/psql <database container ID or Name>` to access the database console
117122

118123
## Users
119124

src/controllers/Sessions.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,16 @@ export default {
2727
Sessions
2828
.auth(req, res)
2929
.then(auth => {
30-
res.status(auth.status).send(auth.data)
30+
res.status(auth.status).send(auth.responseData)
3131
})
3232
.catch(error => {
3333
res.status(400).send(error)
3434
})
3535
},
3636

3737
signOut(req, res) {
38-
Sessions.signOut(req)
38+
Sessions
39+
.signOut(req)
3940
.then(() => {
4041
res.status(200).send()
4142
})

src/lib/Sessions.js

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@ const FILTER_OPTIONS = {
1515
}
1616

1717
Passport.use(new HttpBearerStrategy(
18-
function(token, done) {
19-
const { userId } = verifyToken(null, { token, returnData: true })
18+
{ passReqToCallback: true },
19+
function(req, token, done) {
20+
const { userId } = verifyToken(null, { token, key: process.env.JWT_SECRET, returnData: true })
21+
const ipAddress = getIpAddress(req)
22+
const userAgent = req.headers['user-agent']
23+
24+
if (!userId) return done(null, false)
2025

2126
return find(null, {
22-
where: { userId, token },
27+
where: { token, ipAddress, userAgent },
2328
returnData: true
2429
})
2530
.then(Session => {
@@ -110,15 +115,16 @@ export function find(res, options) {
110115

111116
export function auth(req, res) {
112117
let status = 200, data = {}
113-
const { email, password } = verifyToken(res, { token: req.body.token, returnData: true })
118+
const { token, tkid } = req.body
119+
const { email, password } = verifyToken(res, { token, key: hash(tkid)[0], returnData: true })
114120
const authResponse = {
115121
invalid: {
116122
status: 404,
117-
data: { message: "The email or password you entered doesn't match any account." }
123+
responseData: { message: "The email or password you entered doesn't match any account." }
118124
},
119125
blocked: {
120126
status: 401,
121-
data: { message: 'Your account is blocked. Please contact the administrator.' }
127+
responseData: { message: 'Your account is blocked. Please contact the administrator.' }
122128
}
123129
}
124130

@@ -132,7 +138,9 @@ export function auth(req, res) {
132138
return authResponse.blocked
133139

134140
const date = new Date()
135-
const token = JWT.sign(Object.assign({}, User.json, { date }), process.env.JWT_SECRET, { expiresIn: 86400 })
141+
const key = hash()
142+
const token = JWT.sign({ userId: User.json.userId, date }, process.env.JWT_SECRET, { expiresIn: 86400 })
143+
const data = JWT.sign(_.merge({}, User.json, { date }), key[0], { expiresIn: 86400 })
136144
const sessionData = {
137145
userId: User.json.userId,
138146
userAgent: req.headers['user-agent'],
@@ -143,8 +151,9 @@ export function auth(req, res) {
143151
return DB.Session
144152
.create(sessionData)
145153
.then(() => {
146-
data = Object.assign({}, { token }, data, { redirect: User.json.redirect })
147-
return { status, data }
154+
const responseData = { token, data, redirect: User.json.redirect, tkid: key[1] }
155+
156+
return { status, responseData }
148157
})
149158
})
150159
}
@@ -164,10 +173,8 @@ export function authBearer() {
164173
return Passport.authenticate('bearer', { session: false })
165174
}
166175

167-
function verifyToken(res, { token, returnData }) {
168-
return JWT.verify(
169-
token,
170-
process.env.JWT_SECRET,
176+
function verifyToken(res, { token, key, returnData }) {
177+
return JWT.verify(token, key,
171178
function(errors, decoded) {
172179
if (errors) return returnData ? {} : res.status(401).end()
173180

@@ -251,3 +258,15 @@ function userSQLFn(column, value) {
251258
{ [Op.regexp]: ['\\y', value.toLowerCase(), '\\y'].join('') }
252259
)
253260
}
261+
262+
function hash(index) {
263+
const hashList = process.env.HASH.split('.')
264+
265+
if (index) index = parseInt(index.toString().charAt(index.toString().length - 1), 10)
266+
else index = _.random(0, hashList.length - 1)
267+
268+
return [
269+
hashList[index],
270+
[_.random(1111111, 9999999), index].join('')
271+
]
272+
}

0 commit comments

Comments
 (0)