浏览代码

user authentication

master
kj1352 4 年前
父节点
当前提交
6b92f26f68
共有 4 个文件被更改,包括 249 次插入4 次删除
  1. +130
    -0
      package-lock.json
  2. +5
    -1
      package.json
  3. +53
    -0
      src/authentication/auth.ts
  4. +61
    -3
      src/authentication/routes.ts

+ 130
- 0
package-lock.json 查看文件

@@ -134,6 +134,15 @@
"@types/range-parser": "*"
}
},
"@types/jsonwebtoken": {
"version": "8.5.5",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.5.tgz",
"integrity": "sha512-OGqtHQ7N5/Ap/TUwO6IgHDuLiAoTmHhGpNvgkCm/F4N6pKzx/RBSfr2OXZSwC6vkfnsEdb6+7DNZVtiXiwdwFw==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@@ -154,6 +163,27 @@
"@types/express": "*"
}
},
"@types/passport-jwt": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@types/passport-jwt/-/passport-jwt-3.0.6.tgz",
"integrity": "sha512-cmAAMIRTaEwpqxlrZyiEY9kdibk94gP5KTF8AT1Ra4rWNZYHNMreqhKUEeC5WJtuN5SJZjPQmV+XO2P5PlnvNQ==",
"dev": true,
"requires": {
"@types/express": "*",
"@types/jsonwebtoken": "*",
"@types/passport-strategy": "*"
}
},
"@types/passport-strategy": {
"version": "0.2.35",
"resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz",
"integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==",
"dev": true,
"requires": {
"@types/express": "*",
"@types/passport": "*"
}
},
"@types/qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
@@ -441,6 +471,11 @@
"ieee754": "^1.1.13"
}
},
"buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
},
"builtin-modules": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
@@ -696,6 +731,14 @@
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
"integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
},
"ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -1178,6 +1221,49 @@
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
"integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg="
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"dependencies": {
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
}
}
},
"jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"requires": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"keyv": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
@@ -1194,6 +1280,41 @@
"package-json": "^6.3.0"
}
},
"lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
},
"lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
},
"lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
},
"lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
},
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
},
"lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
},
"lowercase-keys": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
@@ -1493,6 +1614,15 @@
"pause": "0.0.1"
}
},
"passport-jwt": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz",
"integrity": "sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==",
"requires": {
"jsonwebtoken": "^8.2.0",
"passport-strategy": "^1.0.0"
}
},
"passport-strategy": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",


+ 5
- 1
package.json 查看文件

@@ -19,16 +19,20 @@
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"mongodb": "^4.1.2",
"nodemon": "^2.0.12",
"passport": "^0.5.0"
"passport": "^0.5.0",
"passport-jwt": "^4.0.0"
},
"devDependencies": {
"@types/bcrypt": "^5.0.0",
"@types/cors": "^2.8.12",
"@types/express": "^4.17.13",
"@types/jsonwebtoken": "^8.5.5",
"@types/node": "^16.9.4",
"@types/passport": "^1.0.7",
"@types/passport-jwt": "^3.0.6",
"tslint": "^6.1.3",
"typescript": "^4.4.3"
}


+ 53
- 0
src/authentication/auth.ts 查看文件

@@ -0,0 +1,53 @@
import bcrypt from 'bcrypt';
import passport from 'passport';
import passportJWT, { StrategyOptions } from 'passport-jwt';
import jwt from 'jsonwebtoken';
import { getDatabaseClient, DB_NAME } from '../db-utils';

const DEFAULT_SECRET = process.env.SECRET_KEY || '02faf720-e46c-4af8-b4f8-8cdc8ba1aaf5';
export const SALT_ROUNDS = 12;

const JwtStrategy = passportJWT.Strategy;
const ExtractJwt = passportJWT.ExtractJwt;
const strategyOptions: StrategyOptions = {
jwtFromRequest: ExtractJwt.fromExtractors([
ExtractJwt.fromAuthHeaderAsBearerToken(),
ExtractJwt.fromUrlQueryParameter('token')
]),
secretOrKey: DEFAULT_SECRET,
};

passport.use(new JwtStrategy(strategyOptions, async (jwtPayload, done) => {
const usersCollection = getDatabaseClient().db(DB_NAME).collection('users');
try {
const user = await usersCollection.findOne({
_id: jwtPayload.sub
});

if (user && !user.archived) {
return done(null, user);
} else {
return done(null, false);
}

} catch (error) {
return done(error, false);
}
}));

export function generateJWT(id: string) {
const today = new Date();
const expirationDate = new Date(today);
expirationDate.setDate(today.getDate() + 60);
expirationDate.setHours(0);
expirationDate.setMinutes(0);
expirationDate.setSeconds(0);
expirationDate.setMilliseconds(0);

const signedToken = jwt.sign({
sub: id,
exp: expirationDate.getTime() / 1000,
}, DEFAULT_SECRET);

return signedToken;
}

+ 61
- 3
src/authentication/routes.ts 查看文件

@@ -1,11 +1,10 @@
import express, { response, urlencoded } from 'express';
import express from 'express';
import { DB_NAME, getDatabaseClient } from '../db-utils';
import bcrypt from 'bcrypt';
import { generateJWT, SALT_ROUNDS } from './auth';

const authRoutes = express.Router();

export const SALT_ROUNDS = 12;

authRoutes.get('/users/', async (request, response) => {
console.log(request);
response.send("List of users will be displayed");
@@ -67,4 +66,63 @@ authRoutes.post('/register-applicant/', async (request, response) => {

});

authRoutes.post('/api-auth/', async (request, response) => {
const email = request.body.email;
const password = request.body.password;
const userType = request.body.userType;

if (!email || !password || !userType) {
response.status(400);
response.send("Please field the required fields");
return;
}

const userCollection = getDatabaseClient().db(DB_NAME).collection('users');

let users = await userCollection.find({
email,
userType,
}).toArray();

const matchedUser = users[0];

if (!matchedUser) {
response.status(400);
response.send('Wrong credentials');
return;
} else if (!matchedUser.isVerified) {
response.status(400);
response.send('Please complete user verification');
return;
}

let passwordComparisonResult: boolean;

try {
passwordComparisonResult = await bcrypt.compare(password, matchedUser.password);

if (passwordComparisonResult) {
response.send({
id: matchedUser._id,
token: generateJWT(matchedUser._id),
});
} else {
response.status(400);
response.send('Wrong credentials');
}

} catch(e) {
response.sendStatus(500);
response.json(e);
}

return;

// let passwordComparisonResult: boolean;

// try {
// passwordComparisonResult = await bcrypt.compare(password, user.password);
// }
});

export default authRoutes;

正在加载...
取消
保存