Skip to content

Commit df58ebf

Browse files
committed
fix auth server
1 parent e71a76f commit df58ebf

File tree

6 files changed

+177
-104
lines changed

6 files changed

+177
-104
lines changed

Diff for: 11 Axios/03_callbacks/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const getBooks = (err, success) => {
2727
};
2828

2929
- export const postBook = (book) => {
30-
export const postBook = (book) => (err, success) => {
30+
+export const postBook = (book) => (err, success) => {
3131
axios.post('http://localhost:8000/api/books', book)
3232
- .then(() => getBooks())
3333
- .catch(errorHandler);

Diff for: 11 Axios/07b_interceptors/README.MD

+121-62
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
1-
## We're going to create a new page that will contain a login form, if we're authenticated, the response will return a JWT, that we will use to call an API. If everythoi
1+
## We're going to create a new page that will contain a login form, if we're authenticated, the response will return a JWT, that we will use to call an API. If everything goes fine we well allow to access to server resources.
22

3-
* Lets start by creating a _index.html_
3+
* For this demo we will create a new project.
4+
5+
```
6+
npm init -y
7+
```
8+
9+
```
10+
npm i axios -S
11+
```
12+
13+
```
14+
npm i parcel -D
15+
```
16+
17+
* Lets start by creating _index.html_ in root folder solution.
418

519
```html
620
<!DOCTYPE html>
@@ -31,6 +45,9 @@
3145

3246
</html>
3347
```
48+
49+
* All our solution code will be placed in __src__ folder. Create this folder in root folder solution.
50+
3451
* Lets create the code to handle this _form_, first we're going to create a new entry in _src/API/loginAPI.js_
3552

3653
```javascript
@@ -41,53 +58,96 @@ export default ({username, password}) => (
4158
);
4259
```
4360

44-
* Now it's time handle the UI code, but first we're going to create a new style of handling events, a way that allow us to retun _promises_, create _src/asynApi.js_
61+
* Now it's time handle the UI code, but first we're going to create a new style for handling events, we're going o create an event emitter. Create __src/eventEmitter.js__
4562

4663
```javascript
47-
export const submitButtonPromise = (event, targetId) => (
48-
new Promise((resolve, _) => {
49-
document.getElementById(targetId)
50-
.addEventListener(event, (evt) => {
51-
evt.stopPropagation();
52-
evt.preventDefault();
53-
resolve();
54-
});
55-
})
56-
);
64+
const observer = () => {
65+
const observers = [];
66+
return {
67+
subscribe(f) {
68+
observers.push(f);
69+
},
70+
unsubscibe(f) {
71+
observers = observers.filter((subscriber) => subscriber !== f);
72+
},
73+
notify(data) {
74+
observers.forEach((observer) => observer(data));
75+
}
76+
}
77+
};
78+
79+
export const eventSubscription = (targetId) => (event) => {
80+
const eventTarget = document.getElementById(targetId);
81+
82+
let obs = observer();
83+
84+
eventTarget.addEventListener(event, (evt) => {
85+
evt.stopPropagation();
86+
evt.preventDefault();
87+
obs.notify(evt);
88+
});
89+
90+
return obs;
91+
}
92+
5793
```
5894

5995
* Now we can create _src/app.js_
6096

6197
```javascript
62-
// import { appendElement, createList } from './view/uiBuilder';
63-
import { submitButtonPromise } from './asyncApi';
98+
import { eventSubscription } from './eventEmitter';
6499
import login from './API/loginAPI';
65100

66-
67101
const readCredentials = () => {
68102
const username = document.getElementById('username').value;
69103
const password = document.getElementById('password').value;
70104
return {
71105
username,
72-
password,
73-
};
106+
password
107+
}
74108
};
75109

76110
document.addEventListener('DOMContentLoaded', () => {
77-
submitButtonPromise('click', 'login')
78-
.then(() => {
79-
const credentials = readCredentials();
80-
return login(credentials)
81-
})
82-
.then((token) => {
83-
console.log(token);
84-
})
85-
.catch((err) => console.log(err));
111+
const submitButton = eventSubscription('login');
112+
submitButton('click').subscribe(() => {
113+
const credentials = readCredentials();
114+
login(credentials)
115+
.then(({data}) => {
116+
console.log(data);
117+
})
118+
.catch(err => console.log(err));
119+
});
86120
});
87121
```
122+
123+
* Modify __package.json__ to start our app
124+
125+
```diff
126+
{
127+
"name": "temp_auth_review",
128+
"version": "1.0.0",
129+
"description": "",
130+
"main": "index.js",
131+
"scripts": {
132+
+ "start": "parcel index.html",
133+
"test": "echo \"Error: no test specified\" && exit 1"
134+
},
135+
"keywords": [],
136+
"author": "",
137+
"license": "ISC",
138+
"dependencies": {
139+
"axios": "^0.19.0"
140+
},
141+
"devDependencies": {
142+
"parcel": "^1.12.3"
143+
}
144+
}
145+
146+
```
147+
88148
* With our _auth_ server up and running we can check that this is already working.
89149

90-
* Ok, so we're retrieving our token we wan to inject it so lets define _src/API/interceptors.js_
150+
* Ok, so we're retrieving our token we want to inject it so lets define _src/API/interceptors.js_
91151

92152
```javascript
93153
import axios from 'axios';
@@ -104,7 +164,7 @@ export const setUpRequest = (token) => {
104164
* Change _src/app.js_ to use the token;
105165

106166
```diff
107-
import { submitButtonPromise } from './asyncApi';
167+
import { eventSubscription } from './eventEmitter';
108168
import login from './API/loginAPI';
109169
+import { setUpRequest } from './API/interceptors';
110170

@@ -113,22 +173,22 @@ const readCredentials = () => {
113173
const password = document.getElementById('password').value;
114174
return {
115175
username,
116-
password,
117-
};
176+
password
177+
}
118178
};
119179

120180
document.addEventListener('DOMContentLoaded', () => {
121-
submitButtonPromise('click', 'login')
122-
.then(() => {
123-
const credentials = readCredentials();
124-
return login(credentials)
125-
})
126-
- .then((token) => {
127-
+ .then((result) => {
128-
+ const { access_token } = result.data;
129-
+ setUpRequest(access_token);
130-
})
131-
.catch((err) => console.log(err));
181+
const submitButton = eventSubscription('login');
182+
submitButton('click').subscribe(() => {
183+
const credentials = readCredentials();
184+
login(credentials)
185+
- .then(({data}) => {
186+
+ .then(({data}) => {
187+
+ const { access_token } = data;
188+
+ setUpRequest(access_token);
189+
+ })
190+
.catch(err => console.log(err));
191+
});
132192
});
133193
```
134194

@@ -158,7 +218,7 @@ document.addEventListener('DOMContentLoaded', () => {
158218
* Lets edit _src/app.js_ as follows
159219

160220
```javascript
161-
import { submitButtonPromise } from './asyncApi';
221+
import { eventSubscription } from './eventEmitter';
162222
import login from './API/loginAPI';
163223
import { setUpRequest } from './API/interceptors';
164224
/*diff*/
@@ -170,29 +230,28 @@ const readCredentials = () => {
170230
const password = document.getElementById('password').value;
171231
return {
172232
username,
173-
password,
174-
};
233+
password
234+
}
175235
};
176236

177237
document.addEventListener('DOMContentLoaded', () => {
178-
submitButtonPromise('click', 'login')
179-
.then(() => {
180-
const credentials = readCredentials();
181-
return login(credentials)
182-
})
183-
.then((result) => {
184-
const { access_token } = result.data;
185-
setUpRequest(access_token);
186-
})
187-
.catch((err) => console.log(err));
238+
const submitButton = eventSubscription('login');
239+
submitButton('click').subscribe(() => {
240+
const credentials = readCredentials();
241+
login(credentials)
242+
.then(({data}) => {
243+
const { access_token } = data;
244+
setUpRequest(access_token);
245+
})
246+
.catch(err => console.log(err));
247+
});
188248
/*diff*/
189-
document.getElementById('cars')
190-
.addEventListener('click', (event) => {
191-
event.stopPropagation();
192-
axios.get('http://localhost:3050/api/cars')
193-
.then((result) => console.log(result))
194-
.catch((err) => console.log(err));
195-
});
249+
const loadCarsButton = eventSubscription('cars');
250+
loadCarsButton('click').subscribe(() => {
251+
axios.get('http://localhost:3050/api/cars')
252+
.then((result) => console.log(result))
253+
.catch((err) => console.log(err));
254+
});
196255
/*diff*/
197256
});
198257
```

Diff for: auth/credentialResolver.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const jwt = require('jsonwebtoken');
2+
3+
const users = [
4+
{ id: 1, username: 'admin', password: 'admin' },
5+
{ id: 2, username: 'guest', password: 'guest' },
6+
];
7+
8+
exports.resolveLogin = (username, password) => {
9+
let status;
10+
let response;
11+
let emptyCredentials = !username || !password;
12+
if (emptyCredentials) {
13+
status = 400;
14+
response = 'You need a username and password';
15+
}
16+
17+
if (!emptyCredentials) {
18+
const user = users.find((u) =>
19+
u.username === username && u.password === password
20+
);
21+
22+
if (!user) {
23+
status = 401;
24+
response = 'User not found';
25+
} else {
26+
const token = jwt.sign(
27+
{
28+
sub: user.id,
29+
username: user.username
30+
},
31+
'mysupersecretkey',
32+
{ expiresIn: '3 hours' }
33+
);
34+
35+
status = 200;
36+
response = { access_token: token };
37+
}
38+
}
39+
40+
return {
41+
status,
42+
response,
43+
}
44+
};

Diff for: auth/index.js

+5-35
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,20 @@
11
const express = require('express');
22
const bodyParser = require('body-parser');
3-
const jwt = require('jsonwebtoken');
43
const cors = require('cors');
4+
const { resolveLogin } = require('./credentialResolver');
55

66

77
const app = express();
88
const PORT = process.env.PORT || 8887;
9-
const users = [
10-
{ id: 1, username: 'admin', password: 'admin' },
11-
{ id: 2, username: 'guest', password: 'guest' },
12-
];
139

1410
app.use(bodyParser.json());
1511
app.use(cors());
1612

17-
app.post('/login', (req, res, next) => {
18-
console.log(req);
13+
app.post('/login', (req, res) => {
1914
const { username, password } = req.body;
20-
21-
if (!username || !password) {
22-
res.status(400)
23-
.send('You need a username and password');
24-
next();
25-
}
26-
27-
const user = users.find((u) =>
28-
u.username === username && u.password === password
29-
);
30-
31-
if (!user) {
32-
res.status(401)
33-
.send('User not found');
34-
next();
35-
}
36-
37-
const token = jwt.sign(
38-
{
39-
sub: user.id,
40-
username: user.username
41-
},
42-
'mysupersecretkey',
43-
{ expiresIn: '3 hours' }
44-
);
45-
46-
res.status(200)
47-
.send({access_token: token});
15+
const { status, response } = resolveLogin(username, password);
16+
res.status(status)
17+
.send(response);
4818
});
4919

5020
app.get('*', (_, res) => {

Diff for: server-in-memory/server.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const jwtCheck = expressjwt({
2121

2222

2323
app.use('/api/users', jwtCheck, users);
24-
app.use('/api/cars', cars);
24+
app.use('/api/cars', jwtCheck, cars);
2525

2626

2727
app.set('port', process.env.PORT || 3050);

0 commit comments

Comments
 (0)