From 4fb8db3d53df548e596539f50c5a7a8acef6c1bd Mon Sep 17 00:00:00 2001 From: "karl.hudgell" <karl.hudgell@bjss.com> Date: Sun, 21 Feb 2021 14:50:25 +0000 Subject: [PATCH] working cookie authentication --- app.js | 27 ++-- client/src/App.js | 4 +- .../components/{About.jsx => Accounts.jsx} | 4 +- client/src/components/Home.jsx | 121 ++++++++++++++---- client/src/components/Navigation.jsx | 6 +- client/src/components/accountTable.jsx | 3 +- client/src/components/index.js | 2 +- lib/checker.js | 2 +- package.json | 2 +- routes/getUserAccounts.js | 7 +- routes/login.js | 26 ++++ routes/readCookie.js | 19 +++ 12 files changed, 176 insertions(+), 47 deletions(-) rename client/src/components/{About.jsx => Accounts.jsx} (76%) create mode 100644 routes/login.js create mode 100644 routes/readCookie.js diff --git a/app.js b/app.js index cb6e975..ffabe39 100644 --- a/app.js +++ b/app.js @@ -9,8 +9,10 @@ var streamsRouter = require('./routes/getStreams'); var getUserAccounts = require('./routes/getUserAccounts') var singleUserCheck = require('./routes/singleCheck') var addAccount = require('./routes/addAccount') +var readCookie = require('./routes/readCookie') +var login = require('./routes/login') var app = express(); -// const basicAuth = require('express-basic-auth') +const basicAuth = require('express-basic-auth') // view engine setup @@ -20,19 +22,26 @@ app.set('view engine', 'jade'); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); -app.use(cookieParser()); +app.use(cookieParser('82e4e438a0705fabf61f9854e3b575af')); app.use(express.static(path.join(__dirname, 'public'))); +const users = { + users: { + 'Karl': 'TEST', + 'Darren': 'TEST', + 'Duly': 'TEST', + }, + challenge: true, + realm: 'foo', +} app.use('/', indexRouter); +app.use('/login', basicAuth(users), login) app.use('/getStreams', streamsRouter); app.use('/getUserAccounts', getUserAccounts); -app.use('/singleCheck', singleUserCheck) -app.use('/addAccount', addAccount) -// app.use(basicAuth({ -// users: { 'BBLBTV': 'BBLBTV' }, -// challenge: true, -// realm: 'foo', -// })) +app.use('/singleCheck', basicAuth(users), singleUserCheck) +app.use('/addAccount', basicAuth(users), addAccount) +app.use('/readCookie', readCookie) + // catch 404 and forward to error handler app.use(function (req, res, next) { diff --git a/client/src/App.js b/client/src/App.js index 4908cb3..5878159 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,6 +1,6 @@ import React from "react"; import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; -import { Navigation, Footer, Home, About, ServerList } from "./components"; +import { Navigation, Footer, Home, Accounts, ServerList } from "./components"; function App() { return ( <div className="App"> @@ -8,7 +8,7 @@ function App() { <Navigation /> <Switch> <Route path="/" exact component={() => <Home />} /> - <Route path="/about" exact component={() => <About />} /> + <Route path="/Accounts" exact component={() => <Accounts />} /> <Route path="/ServerList" exact component={() => <ServerList />} /> </Switch> <Footer /> diff --git a/client/src/components/About.jsx b/client/src/components/Accounts.jsx similarity index 76% rename from client/src/components/About.jsx rename to client/src/components/Accounts.jsx index 7051962..7f3ba3b 100644 --- a/client/src/components/About.jsx +++ b/client/src/components/Accounts.jsx @@ -1,7 +1,7 @@ import React from "react"; import MTable from "./accountTable"; -function About() { +function Accounts() { return ( <div style={{ padding: "30px" }}> <MTable/> @@ -9,4 +9,4 @@ function About() { ); } -export default About; +export default Accounts; diff --git a/client/src/components/Home.jsx b/client/src/components/Home.jsx index c5c26ad..e49df4a 100644 --- a/client/src/components/Home.jsx +++ b/client/src/components/Home.jsx @@ -1,30 +1,103 @@ -import React from "react"; +import React, { useState, useEffect } from "react"; +import ReactDOM from "react-dom"; + +import axios from "axios"; + +function View(props) { + const { screen, setScreen } = props; + + const [data, setData] = useState(); + + const deleteCookie = async () => { + try { + await axios.get("/readCookie/clear"); + setScreen("auth"); + } catch (e) { + console.log(e); + } + }; + + const getData = async () => { + try { + const res = await axios.get("/get-data"); + console.log(res.data); + setData(res.data); + } catch (e) { + console.log(e); + } + }; -function Home() { return ( - <div className="home"> - <div class="container"> - <div class="row align-items-center my-5"> - <div class="col-lg-7"> - <img - class="img-fluid rounded mb-4 mb-lg-0" - src="http://placehold.it/900x400" - alt="" - /> - </div> - <div class="col-lg-5"> - <h1 class="font-weight-light">Home</h1> - <p> - Lorem Ipsum is simply dummy text of the printing and typesetting - industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of - type and scrambled it to make a type specimen book. - </p> - </div> - </div> - </div> + <div> + <p>{screen}</p> + <p>{data}</p> + <button onClick={getData}>Get Data</button> + <button onClick={deleteCookie}>Logout</button> </div> ); } -export default Home; \ No newline at end of file +function App() { + const [screen, setScreen] = useState("auth"); + const [username, setUsername] = useState(); + const [password, setPassword] = useState(); + + const auth = async () => { + try { + const res = await axios.get("/login", { + auth: { username, password }, + }); + + if (res.data.screen !== undefined) { + setScreen('/about'); + } + } catch (e) { + console.log(e); + } + }; + + const readCookie = async () => { + try { + const res = await axios.get("/readCookie"); + + if (res.data.screen !== undefined) { + setScreen(res.data.screen); + } + } catch (e) { + setScreen("auth"); + console.log(e); + } + }; + + useEffect(() => { + readCookie(); + }, []); + + return ( + <div className="App"> + {screen === "auth" ? ( + <div> + <label>Username: </label> + <br /> + <input type="text" onChange={(e) => setUsername(e.target.value)} /> + <br /> + <label>Password: </label> + <br /> + <input + type="password" + onChange={(e) => setPassword(e.target.value)} + /> + <br /> + <button onClick={auth}>Login</button> + </div> + ) : ( + <View screen={screen} setScreen={setScreen} /> + )} + </div> + ); +} + +export default App; + +const rootElement = document.getElementById("root"); +ReactDOM.render(<App />, rootElement); diff --git a/client/src/components/Navigation.jsx b/client/src/components/Navigation.jsx index 7ccdded..85a4615 100644 --- a/client/src/components/Navigation.jsx +++ b/client/src/components/Navigation.jsx @@ -24,11 +24,11 @@ function Navigation(props) { </li> <li class={`nav-item ${ - props.location.pathname === "/about" ? "active" : "" + props.location.pathname === "/accounts" ? "active" : "" }`} > - <Link class="nav-link" to="/about"> - About + <Link class="nav-link" to="/accounts"> + Accounts </Link> </li> <li diff --git a/client/src/components/accountTable.jsx b/client/src/components/accountTable.jsx index 6745ee4..7b47ce4 100644 --- a/client/src/components/accountTable.jsx +++ b/client/src/components/accountTable.jsx @@ -32,8 +32,7 @@ export default class MatDataTable extends Component { } componentDidMount(prevProps) { - const user = "Karl"; - const url = `/getUserAccounts?userName=${user}`; + const url = `/getUserAccounts`; axios.get(url).then((results) => { console.log(results); console.log(results.data); diff --git a/client/src/components/index.js b/client/src/components/index.js index cbcb530..ac9ce89 100644 --- a/client/src/components/index.js +++ b/client/src/components/index.js @@ -1,5 +1,5 @@ export { default as Navigation } from "./Navigation"; export { default as Footer } from "./Footer"; export { default as Home } from "./Home"; -export { default as About } from "./About"; +export { default as Accounts } from "./Accounts"; export { default as ServerList } from "./ServerList"; \ No newline at end of file diff --git a/lib/checker.js b/lib/checker.js index 82d2a61..970c49e 100644 --- a/lib/checker.js +++ b/lib/checker.js @@ -57,7 +57,7 @@ async function main() { console.log('Finished') } -main() +// main() module.exports = { singleCheck, diff --git a/package.json b/package.json index de82b09..fe6c3b0 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "@material-ui/icons": "^4.11.2", "axios": "^0.21.1", "bcrypt": "^5.0.0", - "cookie-parser": "~1.4.4", + "cookie-parser": "^1.4.5", "cryptr": "^6.0.2", "debug": "~2.6.9", "express": "~4.16.1", diff --git a/routes/getUserAccounts.js b/routes/getUserAccounts.js index 99bf108..9e502fc 100644 --- a/routes/getUserAccounts.js +++ b/routes/getUserAccounts.js @@ -5,9 +5,12 @@ const { getUserAccounts } = require('../lib/getUser') /* POST postUser page. */ router.get('/', async function (req, res, next) { - let data = await getUserAccounts(req.query.userName) + if (req.signedCookies.user === undefined) { + res.send('Cookie Not Set') + } else { + let data = await getUserAccounts(req.signedCookies.user) res.send(data) - + } }); module.exports = router; diff --git a/routes/login.js b/routes/login.js new file mode 100644 index 0000000..297b535 --- /dev/null +++ b/routes/login.js @@ -0,0 +1,26 @@ +var express = require('express'); +var router = express.Router(); + +/* GET home page. */ +router.get('/', function (req, res, next) { + const options = { + httpOnly: true, + signed: true, + } + try { + if (req.auth.user === 'Karl') { + res.cookie('user', 'Karl', options) + } + else if (req.auth.user === 'Darren') { + res.cookie('user', 'Darren', options) + } + else if (req.auth.user === 'Duly') { + res.cookie('user', 'Duly', options) + } + } catch (error) { + res.render('index', { title: 'No Auth' }); + } + res.render('index', { title: 'Express' }); +}); + +module.exports = router; diff --git a/routes/readCookie.js b/routes/readCookie.js new file mode 100644 index 0000000..5720219 --- /dev/null +++ b/routes/readCookie.js @@ -0,0 +1,19 @@ +var express = require('express'); +var router = express.Router(); + +/* POST postUser page. */ +router.get('/', async function (req, res, next) { + if (req.signedCookies.user === 'Karl') { + res.send(req.signedCookies); + } else if (req.signedCookies.name === 'user') { + res.send({ screen: 'user' }); + } else { + res.send('No Cookie Set'); + } +}); + +router.get('/clear', (req, res) => { + res.clearCookie('user').end(); + }); + +module.exports = router;