Open temichelle13 opened 1 month ago
To implement Google sign-in on your website, we need to make changes to both the front end and the back end of the application. The front end will include a Google sign-in button, and the back end will handle the OAuth flow using Passport.js. This will allow users to sign up and log in using their Google accounts.
package.json
Add the necessary dependencies for Google OAuth.
{
"name": "studyplanner",
"version": "1.0.0",
"description": "AI assisted study planner",
"main": "app.js",
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js",
"test": "jest --verbose --coverage",
"lint": "eslint .",
"prettier": "prettier --write ."
},
"author": "Tea Larson-Hetrick",
"license": "MIT",
"dependencies": {
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.19.2",
"jsonwebtoken": "^9.0.2",
"mongodb": "^6.3.0",
"mongoose": "^8.0.1",
"morgan": "^1.10.0",
"passport": "^0.6.0",
"passport-google-oauth20": "^2.0.0"
},
"devDependencies": {
"eslint": "^8.54.0",
"jest": "^29.7.0",
"nodemon": "^3.0.1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/temichelle13/StudyPlanner.git"
},
"bugs": {
"url": "https://github.com/temichelle13/StudyPlanner/issues"
},
"homepage": "https://github.com/temichelle13/StudyPlanner#readme",
"keywords": []
}
Run npm install
to install the new dependencies.
index.html
Add a Google sign-in button to the HTML.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Study Planner</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<h1>Study Planner</h1>
</header>
<main>
<section id="schedule">
<h2>Your Schedule</h2>
</section>
<section id="tasks">
<h2>Your Tasks</h2>
<div id="taskForm">
<form>
</form>
</div>
<div id="taskList">
</div>
</section>
<section id="auth">
<h2>Login</h2>
<button id="google-sign-in">Sign in with Google</button>
</section>
</main>
<footer>
<p>© 2023 Study Planner</p>
</footer>
<script src="main.js"></script>
</body>
</html>
auth/providers.json
Add Google OAuth provider configuration.
{
"anon-user": {
"name": "anon-user",
"type": "anon-user",
"disabled": false
},
"api-key": {
"name": "api-key",
"type": "api-key",
"disabled": true
},
"local-userpass": {
"name": "local-userpass",
"type": "local-userpass",
"config": {
"autoConfirm": true,
"resetFunctionName": "resetFunc",
"runConfirmationFunction": false,
"runResetFunction": true
},
"disabled": false
},
"google-oauth": {
"name": "google-oauth",
"type": "oauth2",
"config": {
"clientID": "YOUR_GOOGLE_CLIENT_ID",
"clientSecret": "YOUR_GOOGLE_CLIENT_SECRET",
"authorizationURL": "https://accounts.google.com/o/oauth2/auth",
"tokenURL": "https://oauth2.googleapis.com/token",
"callbackURL": "http://yourapp.com/auth/google/callback",
"scope": ["profile", "email"]
},
"disabled": false
}
}
Replace YOUR_GOOGLE_CLIENT_ID
and YOUR_GOOGLE_CLIENT_SECRET
with your actual Google OAuth client ID and client secret.
routes/userRoutes.js
Add routes for Google OAuth login and callback handling.
const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const passport = require('passport');
const User = require('../models/user');
const router = express.Router();
require('../config/passport');
router.post('/register', async (req, res) => {
try {
const user = new User(req.body);
await user.save();
const token = jwt.sign({ _id: user._id }, process.env.JWT_SECRET, { expiresIn: '1h' });
res.status(201).send({ user, token });
} catch (error) {
res.status(400).send(error);
}
});
router.post('/login', async (req, res) => {
try {
const user = await User.findByCredentials(req.body.email, req.body.password);
const token = jwt.sign({ _id: user._id }, process.env.JWT_SECRET, { expiresIn: '1h' });
res.send({ user, token });
} catch (error) {
res.status(400).send(error);
}
});
router.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }));
router.get('/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
(req, res) => {
res.redirect('/');
}
);
module.exports = router;
config/passport.js
Configure Passport with Google OAuth strategy.
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const User = require('../models/user');
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "/auth/google/callback"
},
async (token, tokenSecret, profile, done) => {
try {
let user = await User.findOne({ googleId: profile.id });
if (!user) {
user = new User({ googleId: profile.id, name: profile.displayName, email: profile.emails[0].value });
await user.save();
}
return done(null, user);
} catch (error) {
return done(error, null);
}
}
));
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser(async (id, done) => {
try {
const user = await User.findById(id);
done(null, user);
} catch (error) {
done(error, null);
}
});
module.exports = passport;
main.js
Add an event listener for the Google sign-in button.
document.addEventListener('DOMContentLoaded', function() {
const taskForm = document.getElementById('taskForm');
const taskList = document.getElementById('taskList');
const googleSignInButton = document.getElementById('google-sign-in');
taskForm.addEventListener('submit', function(e) {
e.preventDefault();
const title = document.getElementById('taskTitle').value;
const description = document.getElementById('taskDescription').value;
const dueDate = document.getElementById('taskDueDate').value;
fetch('/api/tasks', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ title, description, dueDate })
})
.then(response => response.json())
.then(addTaskToList)
.catch(error => console.error('Error:', error));
taskForm.reset();
});
function addTaskToList(task) {
const div = document.createElement('div');
div.innerHTML = `<h3>${task.title}</h3><p>${task.description}</p><p>Due: ${new Date(task.dueDate).toDateString()}</p>`;
taskList.appendChild(div);
}
fetch('/api/tasks')
.then(response => response.json())
.then(tasks => tasks.forEach(addTaskToList))
.catch(error => console.error('Error:', error));
googleSignInButton.addEventListener('click', function() {
const clientId = 'YOUR_GOOGLE_CLIENT_ID';
const redirectUri = 'YOUR_REDIRECT_URI';
const scope = 'profile email';
const responseType = 'token';
const oauthUrl = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}&response_type=${responseType}`;
window.location.href = oauthUrl;
});
});
Replace 'YOUR_GOOGLE_CLIENT_ID'
and 'YOUR_REDIRECT_URI'
with your actual Google client ID and redirect URI.
Ensure your main server file (e.g., app.js
or server.js
) is configured to use sessions and initialize Passport.
const express = require('express');
const session = require('express-session');
const passport = require('passport');
const userRoutes = require('./routes/userRoutes');
const app = express();
app.use(session({
secret: 'your_secret_key',
resave: false,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use('/api', userRoutes);
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
By following these steps, you will have implemented Google sign-in on your website, allowing users to sign up and log in using their Google accounts.
Click here to create a Pull Request with the proposed solution
Files used for this task:
${task.description}
Due: ${new Date(task.dueDate).toDateString()}
`; taskList.appendChild(div); } // Load existing tasks on page load fetch('/api/tasks') .then(response => response.json()) .then(tasks => tasks.forEach(addTaskToList)) .catch(error => console.error('Error:', error)); // Event listener for Google sign-in button googleSignInButton.addEventListener('click', function() { const clientId = 'YOUR_GOOGLE_CLIENT_ID'; // Replace with your actual client ID const redirectUri = 'YOUR_REDIRECT_URI'; // Replace with your actual redirect URI const scope = 'profile email'; const responseType = 'token'; const oauthUrl = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}&response_type=${responseType}`; // Redirect to Google OAuth login page window.location.href = oauthUrl; }); }); ``` ### Explanation: 1. **Google Sign-In Button**: Ensure you have a button with the ID `googleSignInButton` in your HTML file. 2. **Event Listener**: Add an event listener for the Google sign-in button. When clicked, it constructs the OAuth URL with the necessary parameters and redirects the user to the Google OAuth login page. Make sure to replace `'YOUR_GOOGLE_CLIENT_ID'` and `'YOUR_REDIRECT_URI'` with your actual Google client ID and redirect URI. This change will initiate the OAuth flow when the Google sign-in button is clicked, redirecting the user to the Google OAuth login page.
What - description of what you me to do Example: Hey @autopilot implement a Google sign-in on my website. Make changes to the front end and the back end of the application
Why - explain why this is important Example: I want to allow users to signup and login using their Google account