Skip to content

Commit 277515b

Browse files
committed
Finished implementing frontend and backend authenication for user login
1 parent e718f66 commit 277515b

File tree

13 files changed

+266
-62
lines changed

13 files changed

+266
-62
lines changed

backend/user-service/src/app.module.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import { Module } from '@nestjs/common';
22
import { AppController } from './app.controller';
33
import { AppService } from './app.service';
44
import { AuthModule } from './auth/auth.module';
5+
import { ConfigModule } from '@nestjs/config';
56

67
@Module({
7-
imports: [AuthModule],
8+
imports: [AuthModule, ConfigModule.forRoot()],
89
controllers: [AppController],
910
providers: [AppService],
1011
})

backend/user-service/src/auth/auth.controller.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ export class AuthController {
99
@Post('/google/callback')
1010
async handleRedirect(@Req() req: Request, @Res() res: Response) {
1111
console.log("HELLLO")
12-
const {code} = req.body
13-
const tokens = await this.authService.exchangeCodeForTokens(code)
14-
console.log(tokens)
12+
const {token} = req.body
13+
const tokens = await this.authService.verifyJWTToken(token)
1514
res.json(tokens);
1615
}
1716
}
Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
import { Module } from '@nestjs/common';
22
import { AuthController } from './auth.controller';
33
import { AuthService } from './auth.service';
4-
import { ConfigModule } from '@nestjs/config';
4+
import { ConfigModule, ConfigService } from '@nestjs/config';
5+
import { JwtModule } from '@nestjs/jwt'
6+
import { jwtSecretKey } from './constants';
7+
58
// import { GoogleStrategy } from './utils/google.strategy';
69

710
@Module({
8-
imports: [ConfigModule],
11+
imports: [ConfigModule,
12+
JwtModule.registerAsync({
13+
imports: [ConfigModule],
14+
useFactory: async (configService: ConfigService) => ({
15+
secret: configService.get<string>('JWT_SECRET'),
16+
global: true
17+
}),
18+
inject: [ConfigService]
19+
})
20+
],
921
controllers: [AuthController],
1022
providers: [AuthService]
1123
})
12-
export class AuthModule {}
24+
export class AuthModule { }
Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
11
import { Injectable } from '@nestjs/common';
2+
import { ConfigService } from '@nestjs/config';
23
import { OAuth2Client } from 'google-auth-library';
4+
import { JwtService } from '@nestjs/jwt';
35

46
@Injectable()
57
export class AuthService {
6-
private oAuth2Client: OAuth2Client;
8+
private oAuth2Client: OAuth2Client;
9+
private clientID: string;
10+
private clientSecret: string;
711

8-
constructor() {
9-
this.oAuth2Client = new OAuth2Client('350585476549-mild3b1ggbtd57t4sduk8qlc7d8suq66.apps.googleusercontent.com',
10-
'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', 'http://localhost:3000');
12+
constructor(private configService: ConfigService, private jwtService: JwtService) {
13+
this.clientID = configService.get<string>('GOOGLE_CLIENT_ID');
14+
this.clientSecret = configService.get<string>('GOOGLE_CLIENT_SECRET');
15+
this.oAuth2Client = new OAuth2Client(this.clientID, this.clientSecret, 'http://localhost:3000');
1116
}
1217

13-
async exchangeCodeForTokens(code: string) {
14-
try {
15-
const { tokens } = await this.oAuth2Client.getToken(code);
16-
17-
return tokens; // Contains access_token, refresh_token, and id_token
18-
} catch (error) {
19-
20-
}
18+
async verifyJWTToken(jwtToken: string) {
19+
const loginTicket = await this.oAuth2Client.verifyIdToken({
20+
idToken: jwtToken,
21+
audience: this.clientID
22+
})
23+
const payload = loginTicket.getPayload();
24+
console.log("PAYLOAD")
25+
console.log(payload);
26+
const tokenData = { sub: payload['sub'], email: payload['email'], name: payload['name'], picture: payload['picture'] }
27+
const accessToken = await this.jwtService.signAsync(tokenData, { expiresIn: 60 });
28+
console.log("THIS IS THE TOKEN ", accessToken);
29+
return {jwtToken: accessToken};
2130
}
2231

2332
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const jwtSecretKey = {
2+
secret: 'eu97kF3Uc86bCrNthxsLTyv4PKaZw2WJ',
3+
};

frontend/package-lock.json

Lines changed: 121 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
"@testing-library/react": "^13.4.0",
99
"@testing-library/user-event": "^13.5.0",
1010
"axios": "^1.7.7",
11+
"js-cookie": "^3.0.5",
12+
"jsonwebtoken": "^9.0.2",
13+
"jwt-decode": "^4.0.0",
1114
"react": "^18.3.1",
1215
"react-dom": "^18.3.1",
1316
"react-router-dom": "^6.26.2",

frontend/src/App.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
import logo from './logo.svg';
22
import { Route, Routes } from 'react-router-dom'
3-
import HomePage from './pages/HomePage'
3+
import LoginPage from './pages/LoginPage'
4+
import ProfilePage from './pages/ProfilePage'
45
import './App.css';
6+
import { UserContextProvider } from './UserContextProvider';
57

68

79
function App() {
810
return (
9-
<Routes>
10-
<Route path='/' element={<HomePage />}/>
11-
</Routes>
11+
<UserContextProvider>
12+
<Routes>
13+
<Route path='/' element={<LoginPage />} />
14+
<Route path='/login' element={<LoginPage />} />
15+
<Route path='/profile' element={<ProfilePage />} />
16+
</Routes>
17+
</UserContextProvider>
1218
);
1319
}
1420

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { useState, createContext, useEffect } from 'react';
2+
import { useNavigate } from 'react-router-dom';
3+
import { jwtDecode } from 'jwt-decode';
4+
5+
export const UserContext = createContext({});
6+
7+
export function UserContextProvider({ children }) {
8+
const [token, setToken] = useState(null);
9+
const [loggedIn, setLoggedIn] = useState(false);
10+
const navigate = useNavigate();
11+
12+
const isTokenValid = (token) => {
13+
const decodedToken = jwtDecode(token);
14+
const currentTime = Date.now() / 1000;
15+
console.log("decoded", decodedToken);
16+
return decodedToken.exp > currentTime;
17+
};
18+
19+
useEffect(() => {
20+
const jwtToken = localStorage.getItem("access_token");
21+
if (jwtToken && isTokenValid(jwtToken)) {
22+
setToken(jwtToken);
23+
setLoggedIn(true);
24+
} else {
25+
localStorage.removeItem('jwtToken');
26+
navigate('/');
27+
}
28+
}, [navigate]);
29+
30+
return (
31+
<UserContext.Provider value={{ token, setToken, loggedIn }}>
32+
{children}
33+
</UserContext.Provider>
34+
);
35+
}

frontend/src/components/GoogleButton.js

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)