Changed JWT implementation.

This commit is contained in:
Mike Cao 2020-07-22 21:33:17 -07:00
parent cb0c912c5b
commit f3f0ad15f2
6 changed files with 48 additions and 13 deletions

View File

@ -1,9 +1,10 @@
import crypto from 'crypto';
import { v5 } from 'uuid';
import jwt from 'jsonwebtoken';
import bcrypt from 'bcrypt';
import { JWT, JWE, JWK } from 'jose';
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/;
const KEY = JWK.asKey(Buffer.from(secret()));
export function sha256(...args) {
return crypto.createHash('sha256').update(args.join('')).digest('hex');
@ -25,14 +26,23 @@ export function isValidHash(s) {
return UUID_REGEX.test(s);
}
export async function createToken(payload, options) {
return jwt.sign(payload, secret(), options);
}
export async function parseToken(token, options) {
return jwt.verify(token, secret(), options);
}
export function checkPassword(password, hash) {
return bcrypt.compare(password, hash);
}
export async function createToken(payload) {
return JWT.sign(payload, KEY);
}
export async function verifyToken(token) {
return JWT.verify(token, KEY);
}
export async function createSecureToken(payload) {
return JWE.encrypt(await createToken(payload), KEY);
}
export async function verifySecureToken(token) {
const result = await JWE.decrypt(token, KEY);
return verifyToken(result.toString());
}

View File

@ -1,6 +1,6 @@
import { getWebsite, getSession, createSession } from 'lib/db';
import { getCountry, getDevice, getIpAddress } from 'lib/utils';
import { uuid, parseToken, isValidHash } from 'lib/crypto';
import { uuid, isValidHash, verifyToken } from 'lib/crypto';
export default async req => {
const { payload } = req.body;
@ -11,7 +11,7 @@ export default async req => {
}
try {
return await parseToken(session);
return await verifyToken(session);
} catch {
const ip = getIpAddress(req);
const { userAgent, browser, os } = getDevice(req);

View File

@ -40,6 +40,7 @@
"dotenv": "^8.2.0",
"geolite2-redist": "^1.0.7",
"is-localhost-ip": "^1.4.0",
"jose": "^1.27.2",
"jsonwebtoken": "^8.5.1",
"maxmind": "^4.1.3",
"next": "9.3.5",

View File

@ -1,5 +1,5 @@
import { serialize } from 'cookie';
import { checkPassword, createToken, secret } from 'lib/crypto';
import { checkPassword, createSecureToken } from 'lib/crypto';
import { getAccount } from 'lib/db';
export default async (req, res) => {
@ -9,7 +9,7 @@ export default async (req, res) => {
if (account && (await checkPassword(password, account.password))) {
const { user_id, username, is_admin } = account;
const token = await createToken({ user_id, username, is_admin });
const token = await createSecureToken({ user_id, username, is_admin });
const expires = new Date(Date.now() + 31536000000);
const cookie = serialize('umami.auth', token, { expires, httpOnly: true });

12
pages/api/verify.js Normal file
View File

@ -0,0 +1,12 @@
import { verifySecureToken } from 'lib/crypto';
export default async (req, res) => {
const { token } = req.body;
try {
const payload = await verifySecureToken(token);
res.status(200).send(payload);
} catch {
res.status(400).send('');
}
};

View File

@ -1175,6 +1175,11 @@
"@nodelib/fs.scandir" "2.1.3"
fastq "^1.6.0"
"@panva/asn1.js@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@panva/asn1.js/-/asn1.js-1.0.0.tgz#dd55ae7b8129e02049f009408b97c61ccf9032f6"
integrity sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==
"@prisma/cli@2.2.2":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@prisma/cli/-/cli-2.2.2.tgz#9689483442277523b5724abdafde69f15b8279f0"
@ -4740,6 +4745,13 @@ jest-worker@^26.0.0:
merge-stream "^2.0.0"
supports-color "^7.0.0"
jose@^1.27.2:
version "1.27.2"
resolved "https://registry.yarnpkg.com/jose/-/jose-1.27.2.tgz#060c6cddf17e90eaa6316b926860b12ab76580fc"
integrity sha512-zLIwnMa8dh5A2jFo56KvhiXCaW0hFjdNvG0I5GScL8Wro+/r/SnyIYTbnX3fYztPNSfgQp56sDMHUuS9c3e6bw==
dependencies:
"@panva/asn1.js" "^1.0.0"
js-levenshtein@^1.1.3:
version "1.1.6"
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"