Skip to content

Commit

Permalink
implement basic authentication between next and express
Browse files Browse the repository at this point in the history
  • Loading branch information
l4lilul3lo committed Dec 22, 2022
1 parent 74561ee commit f6dd75d
Show file tree
Hide file tree
Showing 14 changed files with 582 additions and 157 deletions.
11 changes: 10 additions & 1 deletion express/controllers/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,18 @@ async function logout(req, res) {
if (err) {
res.json({ success: false, message: "Unable to logout." });
} else {
res.clearCookie("connect.sid", { path: "/" });
res.json({ success: true, message: "Logged out." });
}
});
}

module.exports = { register, login, logout };
async function checkAuth(req, res) {
if (req.session && req.session.user_id) {
res.json({ isAuth: true });
} else {
res.json({ isAuth: false });
}
}

module.exports = { checkAuth, register, login, logout };
14 changes: 7 additions & 7 deletions express/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,28 @@ const express = require("express");
const session = require("express-session");
let RedisStore = require("connect-redis")(session);
const Redis = require("ioredis");
const cors = require("cors");
//middleware imports
const helmet = require("helmet");
const customCors = require('./middleware/customCors.js');
const customCors = require("./middleware/customCors.js");
const logging = require("./middleware/logging.js");
const { apiRouter } = require("./routes/apiRouter");
var path = require('path');
var path = require("path");

//Set the absolute directory path of the server(index.js) to the global namespace.
//Set the absolute directory path of the server(index.js) to the global namespace.
//This is needed for the server to find files in the /media/ directory
global.appRoot = path.resolve(__dirname);

const app = express();
//Number of proxies between express server and the client
//This is to make the rate limiter ignore proxy requests
//This is used when there are other services in front of Express such Nginx, Amazon Web, etc.
app.set('trust proxy', 1);
app.set("trust proxy", 1);

// LOAD MIDDLEWARES

customCors(app);
app.use(cors({ origin: "http://localhost:3000", credentials: true }));
//Set http security headers
app.use(helmet());
// app.use(helmet());
// logging(app);
let redisClient = new Redis();
app.use(
Expand Down
2 changes: 1 addition & 1 deletion express/models/Post.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ module.exports = (sequelize, DataTypes, Model) => {
const randomLimit = Math.floor(Math.random() * (50 - 1 + 1)) + 1;
//Retrieve a list of userIDs from the database
const res = await sequelize.query(`SELECT user_id FROM users LIMIT = ?`, { replacements: [randomLimit] });
console.log(res);

//Pick a random userID from the database
const userID = res[0][Math.floor(Math.random() * (randomLimit - 1 + 1)) + 1];

Expand Down
22 changes: 22 additions & 0 deletions express/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion express/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"main": "index.js",
"directories": {
"lib": "lib"
},
},
"scripts": {
"dev": "nodemon -r dotenv/config index.js",
"start": "node -r dotenv/config index.js",
Expand All @@ -30,6 +30,7 @@
"dependencies": {
"bcrypt": "^5.1.0",
"connect-redis": "^6.1.3",
"cors": "^2.8.5",
"date-fns": "^2.29.3",
"dotenv": "^16.0.3",
"express": "^4.18.2",
Expand Down
3 changes: 2 additions & 1 deletion express/routes/authRouter.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const express = require("express");
const { register, login, logout } = require("../controllers/auth");
const { register, login, logout, checkAuth } = require("../controllers/auth");
const { registrationLimiter } = require("../middleware/rateLimiters");
const validateRegistration = require("../middleware/validation/register");
const { checkValidation } = require("../middleware/validation/validationResult");
Expand All @@ -9,5 +9,6 @@ const authRouter = express.Router();
authRouter.post("/register", registrationLimiter, validateRegistration, checkValidation, register);
authRouter.post("/login", login);
authRouter.post("/logout", logout);
authRouter.post("/checkAuth", checkAuth);

module.exports = { authRouter };
80 changes: 49 additions & 31 deletions next/clientAPI/api.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,52 @@
import axios from "axios";

// Client API functions that communicate with the API server

// Axios config
const api = axios.create({
baseURL: `http://${process.env.NEXT_PUBLIC_API_SERVER_URL}:${process.env.NEXT_PUBLIC_API_SERVER_PORT}`,
withCredentials: true,
timeout: 2000, //Timeout response after 2 seconds
});

/* Auth Functions */

export async function login(email, password) {
const response = await api.post("/api/auth/login", {email: email, password: password});
return response.data;
}

export async function register(username, email, password) {
const response = await api.post("/api/auth/register", {username: username, email: email, password: password});
return response.data;
}

export async function logout() {
const response = await api.post("/api/auth/logout");
return response.data;
import fetch from "node-fetch";

class Api {
constructor() {
this._api = axios.create({
baseURL: `http://${process.env.NEXT_PUBLIC_API_SERVER_URL}:${process.env.NEXT_PUBLIC_API_SERVER_PORT}`,
withCredentials: true,
timeout: 2000 //Timeout response after 2 seconds
});
}

get api() {
return this._api;
}

async login(email, password) {
const response = await this.api.post("/api/auth/login", { email: email, password: password });
return response.data;
}

async register(username, email, password) {
const response = await this.api.post("/api/auth/register", {
username: username,
email: email,
password: password
});
return response.data;
}

async logout() {
const response = await this.api.post("/api/auth/logout");
return response.data;
}

async getProfilePic(userid) {
const response = await this.api.get(`/api/users/${userid}/profilepic`, { responseType: "blob" });
return response.data;
}

async checkAuth(req) {
const response = await fetch("http://localhost:5000/api/auth/checkAuth", {
method: "POST",
headers: req.headers
});
const data = await response.json();
return data;
}
}

/* User functions */

export async function getProfilePic(userid) {
const response = await api.get(`/api/users/${userid}/profilepic`, {responseType: 'blob'});
return response.data;
}
const jasmaApi = new Api();
export default jasmaApi;
38 changes: 16 additions & 22 deletions next/components/LogInOutBtn.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React, { useState } from 'react';
import { useQueryClient } from 'react-query';
import React, { useState } from "react";
import { useQueryClient } from "react-query";
import Link from "next/link";
import { useRouter } from 'next/router';
import {logout} from '../clientAPI/api.js';
import { useRouter } from "next/router";
import api from "../clientAPI/api.js";

export default function LogInOutBtn(props) {
const router = useRouter();
const queryClient = useQueryClient();
const [loginState, setLoginState] = useState(props.initialState);

const logoutUser = async (e) => {
const res = await logout();
const res = await api.logout();
//Remove the user credentials from the query cache/storage
queryClient.resetQueries("userCredentials", { exact: true });
setLoginState(false);
Expand All @@ -22,29 +22,23 @@ export default function LogInOutBtn(props) {
else {
router.push(`/login`);
}
}
};

//Choose which button (login btn or logout btn) to render based on logged in or logged out state
return (
<React.Fragment>
{loginState ?
(<button
className="formButtonDefault m-2"
onClick={logoutUser}
>
Logout
</button>)
:
(<Link
href="/login"
>
{loginState ? (
<button
className="formButtonDefault m-2"
className="formButtonDefault m-2"
onClick={logoutUser}
>
Login
Logout
</button>
</Link>)
}
) : (
<Link href="/login">
<button className="formButtonDefault m-2">Login</button>
</Link>
)}
</React.Fragment>
);
}
Loading

0 comments on commit f6dd75d

Please sign in to comment.