I'm trying to upload my user's files to a bucket connected to their uid. So, in order to do it I try to grab their uid from the following code in my upload.js file:
const uploader = document.getElementById("uploader");
const fileButton = document.getElementById("fileButton");
fileButton.addEventListener('change', function(e)
{
// Get file
var file = e.target.files[0];
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
console.log("state = definitely signed in");
firebase.storage().ref('users').child(user.uid + "designs").put(file);
} else {
// No user is signed in.
console.log("state = definitely signed out");
}
});
});
Even after the user is logged in and the it directs them to the new page I always get informed that they aren't signed in. Should I use information from the session cookie instead? Any help would be appreciated!
After a few days I realised that I wasn't calling the id token correlated with the user that is logged in. This solved it:
firebase.auth().onAuthStateChanged(function(user)
{
if (user)
{
// User is signed in.
console.log(user);
user.getIdToken().then(function(idToken)
{ // <------ Check this line
console.log(idToken); // It shows the Firebase token now
});
console.log(user.uid);
firebase.storage().ref('users').child(user.uid + "/designs").put(file);
}
else
{
// No user is signed in.
console.log("state = definitely signed out");
}
});
Related
I want add a user ID to my mysql database after a new user signs in using google auth. This documentation hints at what I should do, but I'm not sure of the details. So far, I've hacked together most of the steps, I think - but I'm learning as I go.
Everything's working, but I'm just not sure of next steps. So assuming a user doesn't exist in my DB, what, specifically do I use to create a new user ID?
This is the closest documentation I could find on what I want to do,but it's vague.
If the user isn't yet in your user database, create a new user record
from the information in the ID token payload, and establish a session
for the user.
https://developers.google.com/identity/sign-in/web/backend-auth
My frontend:
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present.
var id_token = googleUser.getAuthResponse().id_token;
var userName = profile.getName();
var userEmail = profile.getEmail();
var image = profile.getImageUrl();
console.log('new user is:', userName,'the ID is',id_token, 'the email is: ', userEmail, 'and the picture is', image)
// POST NEW USER TO BACK END;
var postUrl = `http://localhost:80/newUser`
// Send the data using post;
try{
$.post(postUrl, {token: id_token, userName: userName, userEmail: userEmail, userProfilePicture: image })
.done(function (data) {
console.log('success sign up clause- data posted to backend')
});
console.log('hello')
}catch(err){
console.log('failed to post to backend')
response.send('Error: ' + err)
}
}
My backend:
const CLIENT_ID = 'MyPresumablyPrivateInfo.apps.googleusercontent.com' const {OAuth2Client} = require('google-auth-library'); const client = new OAuth2Client(CLIENT_ID);
app.post('/newUser', async (request, response) => {
console.log(request.body)
var token = request.body.token
var NewuserName = request.body.userName
var NewuserEmail = request.body.userEmail
//token = NewUserId
// Check authenticity of user id
const client = new OAuth2Client(CLIENT_ID);
async function verify() {
const ticket = await client.verifyIdToken({
idToken: token,
audience: CLIENT_ID,
});
const payload = ticket.getPayload();
const userid = payload['sub'];
console.log('id verified!')
}
verify().catch('error caught:', console.error);
});
Use the sub key in the token payload (email not recommended as it may change).
An identifier for the user, unique among all Google accounts and never
reused. A Google account can have multiple emails at different points
in time, but the sub value is never changed. Use sub within your
application as the unique-identifier key for the user.
Source
I would assume that the user emails are unique so what I would do is hash the user's email
and use it as an id
I usually use MD5 hashing as it can help you later in other stuff like using gavatar
I have a function authenticate of users in node js, and I'm not using an authentication, passport or other lib, I couldn't understand it well, so I did my own authentication function.
However, my function is only authentic for users, it does not create cookies, I need to create cookies on a "expiration date" node, and that as soon as it waits, it redirects me back to the login route. I want to implement this in this function:
function verify(req,res,username,password){
db.serialize(function (){
const query = 'SELECT * from Users WHERE User = (?) AND Password = (?)'
db.all(query,[username, password],function(err,rows){
if(err) {
console.log(err);
}
if(rows.length == 1){
console.log(rows);
console.log("Correct user");
res.render(__dirname + "/View/Home/index.handlebars");
}
else{
console.log("Incorrecto user!")
res.redirect('/login')
}
});
});
}
This is my route in node js
app.get("/login", (req,res) => {
res.render(__dirname + "/View/Home/login.handlebars");
});
app.post("/",(req,res) => {
const username = req.body.username
const password = req.body.password
verify(req,res,username,password)
});
I need to create a cookie within the verify () function if the user is valid and when the cookie expires the user is redirected to the "/ login" route again
Assuming you're using Express server, you can set cookies using res.cookie(name, value, options). options is an object, and the maxAge property is probably what you want, which is a number is miliseconds before it expires. For example, if the user is valid you could do res.cookie('username', username, {maxAge: 172800000 /* two days */}).
You can access the request's cookies with req.cookies, which is an object of cookie name keys and string values. You can check if the 'username' key exists and is valid, and if not, redirect using res.redirect.
function verify(req,res,username,password){
// Place this block wherever you want it to check for a valid cookie
// Depending on the context when this function is called, that might not be at the start
if(typeof(req.cookies.username) != 'string')
res.redirect('/login');
db.serialize(function (){
const query = 'SELECT * from Users WHERE User = (?) AND Password = (?)'
db.all(query,[username, password],function(err,rows){
if(err) {
console.log(err);
}
if(rows.length == 1){
console.log(rows);
console.log("Correct user");
// Set Cookie
res.cookie('username', username, {maxAge: 172800000 /* two days */});
res.render(__dirname + "/View/Home/index.handlebars");
}
else{
console.log("Incorrecto user!")
res.redirect('/login')
}
});
});
}
Use Keycloak
Download
Offical Keycloak Download Page
Install For Linux/Unix
./bin/standalone.sh
** Install For Windows**
\bin\standalone.bat
Use arg -b to Bind network address (default is 127.0.0.1) like so
./bin/standalone.sh -b 192.168.1.150
Install Keycloak-nodejs-connect
npm install keycloak-connect
Official Node.js Example from Github
Reference: Getting Started Guide
I am using express-session module in node.js for session management. I created session for login and getting session Id But, when I checked with postman it shows always same session Id for every login until until session destroy.
How can I create proper sessions with Id and how can I check whether session is live or not using session Id. Finally how to destroy the session with session using session Id.
what I tried is
var userLogin = function(req,callback){
var sess = req.session;
var data = req.body;
var query = "call userLogin(?,?)";
var table = [data.email,data.pass];
query = Repo.format(query,table);
Repo.execute(query,function(err,result){
if(err){
}else{
sess.email = data.email;
sess.pass = data.pass;
console.log("session ID is ",req.sessionID);
if(req.sessionID){
console.log("session is in");
}
else{
console.log("session is out");
}
sess.destroy();
console.log(req.sessionID);
if(req.sessionID){
console.log("aft session is in");
}
else{
console.log("aft session is out");
}
}
outPut(callback,err,result);
});
}
Thank you.
I have started learning Node JS today and have made a chatroom.
When a user connects, it sends their user information to Node and that will store that in a var called user which is created in the anonymous function of io.on('connecting', function ... so I can have multiples of them for multiple users (I think that would work)
When the user disconnects, I remove an object of their user from usersOnline which is indexed by their user.id
I keep getting this error that tells me it is undefined:
Error TypeError: Cannot read property 'id' of undefined
at Socket.<anonymous> (/var/www/html/projects/hbc_chat/index.js:28:27)
The error is where I use delete usersOnline[user.id]
And here is the code:
// server user
var srvUser = {
id: 0,
display_name: 'HabboCreate',
fancy_display_name: 'HabboCreate',
picture: 'http://www.habbocreate.com/userdata/uploads/2f48a19f199bb5f018b3089fd4967902'
};
var usersOnline = {};
io.on('connection', function(socket) {
var user;
socket.on('connected', function(userObj) {
// store user
user = userObj;
// add to users online list
usersOnline[user.id] = user;
// send to clients
updateUsersOnline();
// send joined message
sendMessage(srvUser, user.display_name + ' joined the chat');
console.log(user.display_name + ' connected');
});
socket.on('disconnect', function() {
try {
// remove their user from the online list
delete usersOnline[user.id];
// send to client
updateUsersOnline();
// send left message
sendMessage(srvUser, user.display_name + ' left the chat');
}
catch (err) {
console.log('Error', err);
}
});
....
This does not seem to be a scope issue. Is it possible updateUsersOnline() changes the user info? I just ran this exact code, very similar to yours, without errors:
var usersOnline = {};
io.on('connection', function (socket) {
var user;
socket.on('connected', function (userObject) {
user = userObject;
console.log('user: ' + JSON.stringify(user));
usersOnline[user.id] = user;
console.log(JSON.stringify(usersOnline) + '\n');
});
socket.on('disconnect', function () {
try {
console.log('user: ' + JSON.stringify(user));
delete usersOnline[user.id];
console.log(JSON.stringify(usersOnline) + '\n');
} catch (err) {
console.log('err: ' + err);
}
});
});
I passed a user created like this in the client 'connected' event:
var userObject = {
id: new Date(),
display_name: 'some_name',
};
my_connection.emit('connected', userObject);
After the connected event I closed the connection. This is what the server logged:
user: {"id":"2016-12-17T04:49:05.123Z","display_name":"some_name"}
{"2016-12-17T04:49:05.123Z":{"id":"2016-12-17T04:49:05.123Z","display_name":"some_name"}}
user: {"id":"2016-12-17T04:49:05.123Z","display_name":"some_name"}
{}
No errors, so it seems something is removing the user object or at least its id property in between your connected and disconnect events.
right, well I've figured out what was wrong.
It was where I was on the chatroom page, I would restart the node server, my JavaScript wouldnt emit the user details (It only done so upon load), so when i went to refresh or whatever, disconnect event wouldn't be able to find info in the user variable and error
My fix was to make a request user event client side and then emit that on the server when there's a new connection, as to not rely on the page load sending the details
I'm currently using Firebase such that users sign in with their Google accounts to access the app. However, closing the page/opening the page in a new tab requires the user to sign in again. Is there a way to prevent users from having to re-login?
Here is the login code I am using (the example from the firebase docs)
function firebaseLogin() {
firebase.auth().signInWithPopup(provider).then(function(result) {
var token = result.credential.accessToken;
var user = result.user;
document.getElementById('user-name').innerHTML = user.displayName;
document.getElementById('propic').src = user.photoURL;
addClass(login, 'hidden');
removeClass(logout, 'hidden');
var snackbarData = {
message: 'Login Successful',
timeout: 2000
};
snackbarContainer.MaterialSnackbar.showSnackbar(snackbarData);
console.log(user);
reloadList();
}).catch(function(error) {
var errorCode = error.code;
var errorMessage = error.message;
var email = error.email;
var credential = error.credential;
var snackbarData = {
message: 'Login Unsuccessful',
timeout: 2000
};
snackbarContainer.MaterialSnackbar.showSnackbar(snackbarData);
console.error(error);
});
}
I'm not sure if this is the official way to do it, but I ended up saving the user returned from firebase.auth().currentUser in localStorage, and then checking if a user could be found in localStorage on document load. If a user is found, I just set firebase.auth().currentUser to equal the user from localStorage, and everything seemed to work as intended. (For example, if there wasn't an authenticated user, the client wouldn't be able to make calls to the database, but setting currentUser in this fashion allowed accessing the database.)