Add authentication and authorization

This commit is contained in:
Phillip Kühne 2020-10-02 17:47:13 +02:00
parent 60dfea50c4
commit b28dbba746
9 changed files with 92 additions and 13 deletions

View File

@ -5,7 +5,7 @@
"main": "index.js",
"scripts": {
"start": "node dist/index.js",
"debug": "node --nolazy --inspect-brk=9229 dist/index.js",
"debug": "node --nolazy dist/index.js",
"build": "tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},

View File

@ -1,11 +1,29 @@
import { Request, Response } from "express";
import { Post, BodyParam, Body, Res, Req, JsonController, UseBefore, Get, CookieParam } from "routing-controllers";
import { UserCredential } from "../models/usercredential.model";
import User from "../interfaces/user.interface";
import { JwtMiddleware } from "../middleware/jwt.middleware";
@JsonController("/auth")
export class AuthenticationController {
@Post("/login")
doLogin(@Body() usercredential: UserCredential, @Res() res: any) {
return "//TODO login";
doLogin(@Body() user: User, @Res() res: Response) {
if (user.username === process.env.KQUEUE_USERNAME) {
if (user.password === process.env.KQUEUE_PASSWORD) {
const jwtMiddleware = new JwtMiddleware();
const tokenData = jwtMiddleware.createToken(user);
res.cookie("jwt",tokenData,);
res.status(200);
res.send("Welcome.")
return res;
} else {
// TODO wrong password.
return "Wrong password."
}
} else {
// TODO wrong user.
return "Wrong user."
}
}
@Get("/logout")

View File

@ -0,0 +1,11 @@
class HttpException extends Error {
public status: number;
public message: string;
constructor(status: number, message: string) {
super(message);
this.status = status;
this.message = message;
}
}
export default HttpException;

View File

@ -1,10 +1,12 @@
import "reflect-metadata";
import { createExpressServer } from "routing-controllers";
import { Request, Response } from "express";
import { Action, createExpressServer } from "routing-controllers";
import { QueueController } from "./controllers/queue.controller";
import { SongController } from "./controllers/songs.controller";
import { StatisticsController } from "./controllers/statistics.controller";
import { AuthenticationController } from "./controllers/auth.controller";
import { RpcController } from "./controllers/rpc.controller";
import jwt from "jsonwebtoken";
import * as dotenv from "dotenv";
@ -13,7 +15,34 @@ dotenv.config();
const app = createExpressServer({
routePrefix: "/api",
cors: true,
authorizationChecker: async (action: Action) => {
const req: Request = action.request;
const secret = process.env.KQUEUE_JWTSECRET;
const token = parseCookies(req.headers.cookie)["jwt"];
if (token) {
try {
const verificationResponse = jwt.verify(token, secret);
if (verificationResponse) {
return true;
} else {
return false;
}
} catch (error) {
return false;
}
} else {
return false;
}
},
controllers: [QueueController, SongController, StatisticsController, AuthenticationController, RpcController]
});
app.listen(process.env.KQUEUE_PORT);
function parseCookies(str) {
let rx = /([^;=\s]*)=([^;]*)/g;
let obj = {};
for (let m; m = rx.exec(str);)
obj[m[1]] = decodeURIComponent(m[2]);
return obj;
}

View File

@ -0,0 +1,5 @@
interface DataStoredInToken {
_id: string;
}
export default DataStoredInToken;

View File

@ -0,0 +1,6 @@
interface User {
username: string;
password: string;
}
export default User;

View File

@ -0,0 +1,14 @@
import DataStoredInToken from "../interfaces/dataStoredInToken.interface";
import User from "../interfaces/user.interface";
import * as jwt from 'jsonwebtoken';
export class JwtMiddleware {
public createToken(user: User): string {
const expiresIn = 60 * 60; // an hour
const secret = process.env.KQUEUE_JWTSECRET;
const dataStoredInToken: DataStoredInToken = {
_id: user.username,
};
return jwt.sign(dataStoredInToken, secret, { expiresIn });
}
}

View File

@ -1,4 +0,0 @@
export interface UserCredential {
username: string,
password: string
}

View File

@ -244,12 +244,12 @@ paths:
'200':
description: >
Successfully authenticated.
The session ID is returned in a cookie named `connect.sid`. You need to include this cookie in subsequent requests.
The session ID is returned in a cookie named `jwt`. You need to include this cookie in subsequent requests.
headers:
Set-Cookie:
schema:
type: string
example: connect.sid=abcde12345; Path=/; HttpOnly
example: jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiJhZG1pbiIsImlhdCI6MTYwMTY1MDYwNSwiZXhwIjoxNjAxNjU0MjA1fQ.uGvOlBAZdbPT8U9s7jEt5PUWyxLrpgaf02EoPVC_Zlsd; Path=/; HttpOnly
/auth/logout:
get:
summary: Logs the user out and invalidates the session on the server
@ -345,7 +345,7 @@ components:
cookieAuth: # arbitrary name for the security scheme; will be used in the "security" key later
type: apiKey
in: cookie
name: connect.sid # cookie name
name: jwt # cookie name
schemas:
QueueEntry:
type: object