Reduce the amount of SQL requests made for authentication
This commit is contained in:
parent
95632f5880
commit
272688da26
@ -15,14 +15,15 @@ export default class AuthComponent extends ApplicationComponent<void> {
|
||||
public async init(router: Router): Promise<void> {
|
||||
router.use(async (req, res, next) => {
|
||||
req.authGuard = this.authGuard;
|
||||
res.locals.user = await (await req.authGuard.getProofForSession(req.session!))?.getResource();
|
||||
res.locals.user = await (await req.authGuard.getProof(req))?.getResource();
|
||||
next();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const REQUIRE_REQUEST_AUTH_MIDDLEWARE = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
if (!await req.authGuard.isAuthenticatedViaRequest(req)) {
|
||||
let proof = await req.authGuard.isAuthenticatedViaRequest(req);
|
||||
if (!proof) {
|
||||
req.flash('error', `You must be logged in to access ${req.url}.`);
|
||||
res.redirect(Controller.route('auth', undefined, {
|
||||
redirect_uri: req.url,
|
||||
@ -30,26 +31,31 @@ export const REQUIRE_REQUEST_AUTH_MIDDLEWARE = async (req: Request, res: Respons
|
||||
return;
|
||||
}
|
||||
|
||||
req.models.user = await (await req.authGuard.getProofForRequest(req))?.getResource();
|
||||
req.models.user = await proof.getResource();
|
||||
next();
|
||||
};
|
||||
|
||||
export const REQUIRE_AUTH_MIDDLEWARE = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
if (await req.authGuard.isAuthenticatedViaRequest(req)) {
|
||||
req.models.user = await (await req.authGuard.getProofForRequest(req))?.getResource();
|
||||
next();
|
||||
} else {
|
||||
if (!await req.authGuard.isAuthenticated(req.session!)) {
|
||||
req.flash('error', `You must be logged in to access ${req.url}.`);
|
||||
res.redirect(Controller.route('auth', undefined, {
|
||||
redirect_uri: req.url,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
req.models.user = await (await req.authGuard.getProofForSession(req.session!))?.getResource();
|
||||
// Via request
|
||||
let proof = await req.authGuard.isAuthenticatedViaRequest(req);
|
||||
if (proof) {
|
||||
req.models.user = await proof.getResource();
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// Via session
|
||||
proof = await req.authGuard.isAuthenticated(req.session!);
|
||||
if (!proof) {
|
||||
req.flash('error', `You must be logged in to access ${req.url}.`);
|
||||
res.redirect(Controller.route('auth', undefined, {
|
||||
redirect_uri: req.url,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
req.models.user = await proof.getResource();
|
||||
next();
|
||||
};
|
||||
export const REQUIRE_GUEST_MIDDLEWARE = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
if (await req.authGuard.isAuthenticated(req.session!)) {
|
||||
|
@ -26,7 +26,7 @@ export default abstract class AuthController extends Controller {
|
||||
protected abstract async getCheckAuth(req: Request, res: Response, next: NextFunction): Promise<void>;
|
||||
|
||||
protected async postLogout(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
const proof = await req.authGuard.getProofForSession(req.session!);
|
||||
const proof = await req.authGuard.getProof(req);
|
||||
await proof?.revoke();
|
||||
req.flash('success', 'Successfully logged out.');
|
||||
res.redirect(req.query.redirect_uri?.toString() || '/');
|
||||
|
@ -7,15 +7,47 @@ import {PENDING_ACCOUNT_REVIEW_MAIL_TEMPLATE} from "../Mails";
|
||||
import Mail from "../Mail";
|
||||
import Controller from "../Controller";
|
||||
import config from "config";
|
||||
import ModelFactory from "../db/ModelFactory";
|
||||
|
||||
export default abstract class AuthGuard<P extends AuthProof<User>> {
|
||||
public abstract async getProofForSession(session: Express.Session): Promise<P | null>;
|
||||
protected abstract async getProofForSession(session: Express.Session): Promise<P | null>;
|
||||
|
||||
public async getProofForRequest(req: Request): Promise<P | null> {
|
||||
protected async getProofForRequest(req: Request): Promise<P | null> {
|
||||
return null;
|
||||
}
|
||||
|
||||
public async getProof(req: Request): Promise<P | null> {
|
||||
let proof = await this.isAuthenticatedViaRequest(req);
|
||||
if (!proof && req.session) {
|
||||
proof = await this.isAuthenticated(req.session);
|
||||
}
|
||||
return proof;
|
||||
}
|
||||
|
||||
public async isAuthenticated(session: Express.Session): Promise<P | null> {
|
||||
if (!session.is_authenticated) return null;
|
||||
|
||||
const proof = await this.getProofForSession(session);
|
||||
|
||||
if (!proof || !await proof.isValid() || !await proof.isAuthorized()) {
|
||||
await proof?.revoke();
|
||||
session.is_authenticated = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
return proof;
|
||||
}
|
||||
|
||||
public async isAuthenticatedViaRequest(req: Request): Promise<P | null> {
|
||||
const proof = await this.getProofForRequest(req);
|
||||
|
||||
if (!proof || !await proof.isValid() || !await proof.isAuthorized()) {
|
||||
await proof?.revoke();
|
||||
return null;
|
||||
}
|
||||
|
||||
return proof;
|
||||
}
|
||||
|
||||
public async authenticateOrRegister(
|
||||
session: Express.Session,
|
||||
proof: P,
|
||||
@ -61,28 +93,10 @@ export default abstract class AuthGuard<P extends AuthProof<User>> {
|
||||
}
|
||||
|
||||
// Login
|
||||
session.auth_id = user.id;
|
||||
session.is_authenticated = true;
|
||||
if (onLogin) await onLogin(user);
|
||||
}
|
||||
|
||||
public async isAuthenticated(session: Express.Session): Promise<boolean> {
|
||||
if (typeof session.auth_id !== 'number') return false;
|
||||
|
||||
const proof = await this.getProofForSession(session);
|
||||
|
||||
if (!proof || !await proof.isValid() || !await proof.isAuthorized()) {
|
||||
await proof?.revoke();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async isAuthenticatedViaRequest(req: Request): Promise<boolean> {
|
||||
const proof = await this.getProofForRequest(req);
|
||||
return Boolean(proof && await proof.isValid() && await proof.isAuthorized());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class AuthError extends Error {
|
||||
|
Loading…
Reference in New Issue
Block a user