I am trying to build this google login with normal login(login using user email and password). I have several problem regarding this.( for technologies i am using angular, node.js mysql)
- I am getting the token to my terminal, but it doens’t have the userId.(userId: undefined) how to get it?
- And also does google generate an id? cause in my database i have setup userId to generate automatically and I get that with a google id. But at the sametime it says userId undefined. now i’m confused.
- Even though i got the token, i can’t get it to the local storage(to the frontend).
This is my auth.service.ts file
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { ApiPathsService } from './apipaths/api-paths.service';
import { JwtHelperService } from '@auth0/angular-jwt';
import { Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private baseURL = 'http://localhost:3000';
private userPayload: any;
constructor(private http: HttpClient,private router:Router, private jwtHelper: JwtHelperService) { }
isLoggedIn() {
try {
return !!localStorage.getItem('accessToken');
} catch (error) {
console.log(error);
return false;
}
}
login() {
console.log("Logged in");
}
logout(){
this.signOut();
}
storeToken(token: string) {
localStorage.setItem('accessToken', token)
}
getToken() {
return localStorage.getItem('accessToken');
}
signOut(){
localStorage.clear();
}
loginNew(credentials: { email: string; password: string; }): Observable<any> {
return this.http.post(ApiPathsService.login, credentials);
}
loginWithGoogle(token: string): Observable<any> {
return this.http.post(ApiPathsService.googleAuth, { token });
}
registerUser(user: any): Observable<any> {
return this.http.post<any>(ApiPathsService.register, user);
}
googleLogin() {
window.location.href = `${this.baseURL}/auth/google`;
}
getUserProfile(): Observable<any> {
return this.http.get<any>(`${this.baseURL}/profile`);
}
decodedToken() {
const token = this.getToken();
console.log('Token:', token); // Log token
if (token) {
this.userPayload = this.jwtHelper.decodeToken(token);
console.log('Decoded Payload:', this.userPayload);
return this.userPayload;
}
return null;
}
getEmail() {
const payload = this.decodedToken();
return payload ? payload.email : null;
}
getUserId() {
const payload = this.decodedToken();
return payload ? payload.userId : null;
}
}
api-paths.service.ts file
export class ApiPathsService {
static readonly baseURL:string = 'http://localhost:3000';
static readonly login:string=this.baseURL+'/login';
static readonly register:string=this.baseURL+'/createUser';
static readonly googleAuth: string = this.baseURL + '/auth/google';
static readonly getProfile:string=this.baseURL+'/getProfile';
static readonly updateProfile:string=this.baseURL+'/updateProfile';
}
generateAccessToken.js
const jwt = require("jsonwebtoken");
function generateAccessToken(user) {
const payload = {
userId: user.id, // Assuming user has an id field
email: user.email
};
console.log('Generating token with payload:', payload);
return jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET, { expiresIn: "15m" });
}
module.exports = generateAccessToken;
passport.js
// middlewares/passport.js
require('dotenv').config();
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
const { findUserByEmail, createUserInDb } = require('../models/user');
// Configure Google OAuth
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "http://localhost:3000/auth/google/callback",
scope: ['profile', 'email']
},
async (_accessToken, _refreshToken, profile, done) => {
console.log("googleUser", profile);
try {
// Check for existing user or create new
const existingUser = await findUserByEmail(profile.emails[0].value);
if (existingUser) {
return done(null, existingUser);
}
console.log(profile);
const body = {
email: profile.emails[0].value,
firstName: profile.name.givenName,
lastName: profile.name.familyName,
provider: profile.provider
};
const newUser = await createUserInDb(body);
return done(null, newUser);
} catch (error) {
console.error('Error during Google authentication:', error);
type here
return done(error);
}
}
));
// Serialize user into session
passport.serializeUser((user, done) => {
done(null, user);
});
// Deserialize user from session
passport.deserializeUser((obj, done) => {
done(null, obj);
});
module.exports = passport;
user.js
// models/user.js
const db = require("../models/db");
const findUserByEmail = (email) => {
return new Promise((resolve, reject) => {
db.query('SELECT * FROM userTable WHERE email = ?', [email], (error, results) => {
if (error) {
return reject(error);
}
resolve(results[0]);
});
});
};
const createUserInDb = (user) => {
return new Promise((resolve, reject) => {
const { email, firstName, lastName, provider } = user;
const query = 'INSERT INTO userTable (email, firstname, lastname, provider) VALUES (?, ?, ?, ?)';
db.query(query, [email, firstName, lastName, provider], (error, results) => {
if (error) {
return reject(error);
}
resolve({ id: results.insertId, ...user });
});
});
};
async function findOne(userId) {
console.log(`Finding user with userId: ${userId}`);
return new Promise((resolve, reject) => {
const sql = 'SELECT * FROM userTable WHERE userId = ?';
db.query(sql, [userId], (err, results) => {
if (err) {
console.error('Error executing SQL query:', err);
reject(err);
return;
}
if (results.length > 0) {
resolve(results[0]); // Resolve with the first user found (assuming userId is unique)
} else {
resolve(null); // Resolve with null if no user found
}
});
});
}
async function updateUserById(userId, updateFields) {
return new Promise((resolve, reject) => {
const { firstName, lastName, password, location, subLocation } = updateFields;
const sql = 'UPDATE userTable SET firstName = ?, lastName = ? , password = ? , location = ?, subLocation = ? WHERE userId = ?';
db.getConnection((err, connection) => {
if (err) {
reject(err);
return;
}
connection.query(sql, [firstName, lastName, password, location, subLocation, userId], (err, result) => {
connection.release();
if (err) {
reject(err);
return;
}
resolve(result.affectedRows); // Return number of affected rows
});
});
});
}
module.exports = { findUserByEmail, createUserInDb, findOne, updateUserById};
thirdPartyAuthController.js
const generateAccessToken = require('../generateAccessToken');
const ThirdPartyAuth = async (req, res, next) => {
try{
const user = req.user;
const token = generateAccessToken({ id: user.id, email: user.email });
console.log(token);
res.cookie('accessToken', token, { httpOnly: true, secure: process.env.NODE_ENV === 'production' });
res.redirect('http://localhost:4200/homepage');
} catch (error) {
console.error('Error during third party authentication:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
}
module.exports = ThirdPartyAuth;
I just dont understand the issue, and where is it?
Buddhini Watagala is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.