I have reactjs admin panel for my project admin module. I have requirement that is if 2 user have same userId and password then both of them can not login in same time. If User1 already has logged into admin panel then User2 should not be login. I have get Id token of logged in user and saved it into database now I wanted to check whether the user is already login or not.
I dont have any idea how to prevent user to login in admin panel if other user is already logged in.
Please show some light on code and suggest me right path to fulfill my requirement
Here is my code:
//AUTHENTICATION
var loggedIn = false;
var activeSession = true;
if (Config.firebaseConfig.apiKey) {
firebase.auth().onAuthStateChanged(function (user) {
// Retriving ID Token
var Auth = firebase.auth();
var idToken = Auth.currentUser.getToken();
firebase.database().ref('activeSession').push({
idToken:idToken,
userEmail : user.email,
userId: user.uid,
isUserLoggedIn : activeSession
});
firebase.auth().verifyIdToken(idToken).then(function(decodedToken) {
console.log(decodedToken);
var uid = decodedToken.uid;
console.log(uid);
// ...
}).catch(function(error) {
// Handle error
});
}).catch(function(error) {
// Handle error
console.log(error);
});
if (user) {
// User is signed in.
console.log("User is signed in " + user.email);
if (Config.adminConfig.allowedUsers != null && Config.adminConfig.allowedUsers.indexOf(user.email) == -1) {
//Error, this user is not allowed anyway
alert("The user " + user.email + " doens't have access to this admin panel!");
firebase.auth().signOut();
} else {
loggedIn = true;
displayApp();
}
} else {
// No user is signed in.
console.log("No user is signed in ");
loggedIn = false;
displayApp();
if (window.display) {
window.display();
}
}
} else {
// No user is signed in.
console.log("No user is signed in, step 1 ");
loggedIn = false;
displayApp();
if (window.display) {
window.display();
}
}
function displayApp() {
if (loggedIn) {
ReactDOM.render(
<Admin />,
document.getElementById('root')
);
} else {
ReactDOM.render(
<Login />,
document.getElementById('root')
);
}
}
displayApp();
Related
firebase
.database().
ref('UsersList/' + firebase.auth().currentUser.uid)
.once('value').then(snapshot => {
console.log(snapshot.val())
});
that's my code which I am using in componentDidMount() function on the home page after signing up a user.
Set an authentication state observer and get user data :
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
var displayName = user.displayName;
var email = user.email;
var emailVerified = user.emailVerified;
var photoURL = user.photoURL;
var isAnonymous = user.isAnonymous;
var uid = user.uid;
var providerData = user.providerData;
// ...
} else {
// User is signed out.
// ...
}
});
I have a login form which have username and password fields in it. I want to authenticate username and password with Oidc Client . This is a method that was used for signing in by default:
async signIn(state) {
await this.ensureUserManagerInitialized();
try {
const silentUser = await this.userManager.signinSilent(this.createArguments());
this.updateState(silentUser);
return this.success(state);
} catch (silentError) {
// User might not be authenticated, fallback to popup authentication
console.log("Silent authentication error: ", silentError);
try {
if (this._popUpDisabled) {
throw new Error('Popup disabled. Change \'AuthorizeService.js:AuthorizeService._popupDisabled\' to false to enable it.')
}
const popUpUser = await this.userManager.signinPopup(this.createArguments());
this.updateState(popUpUser);
return this.success(state);
} catch (popUpError) {
if (popUpError.message === "Popup window closed") {
// The user explicitly cancelled the login action by closing an opened popup.
return this.error("The user closed the window.");
} else if (!this._popUpDisabled) {
console.log("Popup authentication error: ", popUpError);
}
// PopUps might be blocked by the user, fallback to redirect
try {
await this.userManager.signinRedirect(this.createArguments(state));
return this.redirect();
} catch (redirectError) {
console.log("Redirect authentication error: ", redirectError);
return this.error(redirectError);
}
}
}
}
Method was called from Login.js :
async login(returnUrl) {
const state = {returnUrl };
const result = await authService.signIn(state);
switch (result.status) {
case AuthenticationResultStatus.Redirect:
break;
case AuthenticationResultStatus.Success:
await this.navigateToReturnUrl(returnUrl);
break;
case AuthenticationResultStatus.Fail:
this.setState({ message: result.message });
break;
default:
throw new Error(`Invalid status result ${result.status}.`);
}
}
Now i have a custom login form. I will have value of user-entered username and password but I have no idea of authenticating it. How can it be done?
Unfortunately it's not supported by the library yet.
https://github.com/IdentityModel/oidc-client-js/issues/234
I am trying to do authentication using identity server 4 for my react app.i followed this documentation.I am using implicit flow of identity server so onload application it will go to login page of identity server. after giving proper username and password it will validate and give a token.Everything is working as expected but i am not able to redirect my react app to Dashboard page.I am very new to react please help me.
// Copyright (c) Microsoft. All rights reserved.
import Config from 'app.config';
import AuthenticationContext from 'adal-angular/dist/adal.min.js'
import { Observable } from 'rxjs';
import { HttpClient } from 'utilities/httpClient';
import { toUserModel, authDisabledUser } from './models';
import Oidc, { User } from 'oidc-client';
const ENDPOINT = Config.serviceUrls.auth;
export class AuthService {
//static authContext; // Created on AuthService.initialize()
//static authEnabled = true;
//static aadInstance = '';
//static appId = '00000000-0000-0000-0000-000000000000';
//static tenantId = '00000000-0000-0000-0000-000000000000';
//static clientId = '00000000-0000-0000-0000-000000000000';
static initialize() {
if (typeof global.DeploymentConfig === 'undefined') {
alert('The dashboard configuration is missing.\n\nVerify the content of webui-config.js.');
throw new Error('The global configuration is missing. Verify the content of webui-config.js.');
}
if (typeof global.DeploymentConfig.authEnabled !== 'undefined') {
AuthService.authEnabled = global.DeploymentConfig.authEnabled;
if (!AuthService.authEnabled) {
console.warn('Auth is disabled! (see webui-config.js)');
}
}
//AuthService.tenantId = global.DeploymentConfig.aad.tenant;
//AuthService.clientId = global.DeploymentConfig.aad.appId;
//AuthService.appId = global.DeploymentConfig.aad.appId;
//AuthService.aadInstance = global.DeploymentConfig.aad.instance;
if (AuthService.aadInstance && AuthService.aadInstance.endsWith('{0}')) {
AuthService.aadInstance = AuthService.aadInstance.substr(0, AuthService.aadInstance.length - 3);
}
// TODO: support multiple types/providers
if (AuthService.isEnabled() && global.DeploymentConfig.authType !== 'aad') {
throw new Error(`Unknown auth type: ${global.DeploymentConfig.authType}`);
}
//AuthService.authContext = new AuthenticationContext({
// instance: AuthService.aadInstance,
//tenant: AuthService.tenantId,
//clientId: AuthService.clientId,
//redirectUri: "http://localhost:3000/dashboard",
//expireOffsetSeconds: 300, // default is 120
//postLogoutRedirectUri: window.location.protocol
//});
}
static isDisabled() {
return AuthService.authEnabled === false;
}
static isEnabled() {
return !AuthService.isDisabled();
}
static onLoad(successCallback) {
debugger;
AuthService.initialize();
if (AuthService.isDisabled()) {
console.debug('Skipping Auth onLoad because Auth is disabled');
if (successCallback) successCallback();
return;
};
var config = {
authority: "http://localhost:5000",
client_id: "mvc",
redirect_uri: "http://localhost:3000/dashboard",
response_type: "id_token token",
post_logout_redirect_uri : "http://localhost:5003/index.html",
};
var mgr = new Oidc.UserManager(config);
mgr.signinRedirect();
mgr.getUser().then(function(user){
if(user){
console.log("User logged in", user.profile);
}
else {
console.log("User not logged in");
}
});
mgr.events.addUserLoaded(function(userLoaded){
mgr.User=userLoaded;
})
mgr.events.addSilentRenewError(function (error){
console.log('the user has signrd out');
mgr._user=null;
})
//mgr.login();
//mgr.renewToken();
// Note: "window.location.hash" is the anchor part attached by
// the Identity Provider when redirecting the user after
// a successful authentication.
// if (AuthService.authContext.isCallback(window.location.hash)) {
// console.debug('Handling Auth Window callback');
// // Handle redirect after authentication
// AuthService.authContext.handleWindowCallback();
// const error = AuthService.authContext.getLoginError();
// if (error) {
// throw new Error(`Authentication Error: ${error}`);
// }
// } else {
// AuthService.getUserName(user => {
// if (user) {
// console.log(`Signed in as ${user.Name} with ${user.Email}`);
// if (successCallback) successCallback();
// } else {
// console.log('The user is not signed in');
// AuthService.authContext.login();
// }
// });
// }
}
static getUserName(callback) {
if (AuthService.isDisabled()) return;
if (AuthService.authContext.getCachedUser()) {
Observable.of({ Name:AuthService.authContext._user.userName, Email: AuthService.authContext._user.userName })
.map(data => data ? { Name: data.Name, Email: data.Email } : null)
.subscribe(callback);
} else {
console.log('The user is not signed in');
AuthService.authContext.login();
}
}
/** Returns a the current user */
static getCurrentUser() {
if (AuthService.isDisabled()) {
return Observable.of(authDisabledUser);
}
return HttpClient.get(`${ENDPOINT}users/current`)
.map(toUserModel);
}
static logout() {
if (AuthService.isDisabled()) return;
AuthService.authContext.logOut();
AuthService.authContext.clearCache();
}
/**
* Acquires token from the cache if it is not expired.
* Otherwise sends request to AAD to obtain a new token.
*/
static getAccessToken() {
debugger;
if (AuthService.isDisabled()) {
return Observable.of('client-auth-disabled');
}
return Observable.create(observer => {
return AuthService.authContext.acquireToken(
AuthService.appId,
(error, accessToken) => {
if (error) {
console.log(`Authentication Error: ${error}`);
observer.error(error);
}
else observer.next(accessToken);
observer.complete();
}
);
});
}
}
The problem i am facing is after authentication my app is going some kind of loop means the url of app is changing to identity server and local app url.you can see my app was using AuthenticationContext from adal previously.i want to change into oidc for identity server4.
I see that you mentioned redirect uri as dashboard? 'redirect_uri: "http://localhost:3000/dashboard'. So from the Identity server, the user will be redirected here right? Can you show us what you are doing on the dashboard page?
Typically, in Identity server implementation, redirect Uri needs to be a simple page whose responsibility needs to be nothing but accessing the Tokens from the URL and redirecting to the desired page (like redirecting to the dashboard from here)
I understand what I gave you is more of a theoretical answer, but seeing your implementation of redirect URL help you get a better answer.
the function runs and console.log shows the user object on the backend. I don't understand why it's telling me there is an issue here, and really need some guidance.
vm.register = function() {
//check that passwords match
if(vm.password != vm.passwordRepeat) {
vm.registerError = "Passwords must match.";
return;
} else {
var username = vm.username;
// console.log("Valid form. Checking for existing user",username);
storeDataFactory.userExists(username).then(function(response){
//if user exists, return error
if(response.data.length > 0) {
vm.registerError = "A user with email " + username + " already exists. Please login.";
return;
} else {
//if no user exists
if(response.data.length == 0) {
// console.log("No user exists. Continue with registration.");
}
//assign info to user object
var user = {
username: vm.username,
password: vm.password,
name: vm.name,
phone: vm.phone
};
**storeDataFactory.createUser(user).then(function(response){**
vm.user = response.data;
console.log("Created user", vm.user);
if(response.data.length > 0) {
console.log("Created user", vm.user);
vm.registerMessage = "Successful registration, please login";
vm.registerError = null;
vm.user = response.data;
}
}).catch(function(error){
console.log(error);
vm.registerError = "There was an error creating your account.";
vm.registerMessage = null;
});
}
});
}
};
The backend code:
module.exports.register = function(req, res) {
console.log('registering user', req.body);
//create the user object with hashed pass
User
.create({
username: req.body.username,
name: req.body.name,
phone: req.body.phone,
password: bcrypt.hashSync(req.body.password, bcrypt.genSaltSync(10))
}, function(err, user) {
if (err) {
console.log("Error creating account");
res
.status(400)
.json(err);
} else {
console.log("Account created!", user);
res
.status(201)
.json(user);
}
});
};
Account created! and the user object are logged on the backend. It just won't display that damn Successful Registration! Please login. message.
storeDataFactory code:
/* global angular */ angular.module('rumbleApp').factory('storeDataFactory', storeDataFactory);
function storeDataFactory($http) {
return {
userExists: userExists,
createUser: createUser
};
function userExists(username) {
return $http.get('/api/users/userExists/' + username).then(complete).catch(failed);
}
function createUser(user) {
$http.post('/api/users/register', user).then(complete).catch(failed);
}
function complete(response) {
return response;
}
function failed(error) {
console.log(error.statusText);
return "There was an error with the API call.";
}
}
Are you sure you're returning from storeDataFactory.createUser()? Can you post the code for that method?
Sounds like the code is executing, but you're not returning anything from it (hence why it thinks it's undefined)
I have been experimenting with various ways to obtain the current user profile from a database, just like I used to use session_start() in PHP to get all the variables I need.
Here is my data structure:
{
"users" : {
"7fb5c5fd-34fe-47da-b5e9-f8faa23aea1c" : {
"email" : "bl#bt.com",
"firstname" : "bla",
"lastname" : "bear",
"uid" : "7fb5c5fd-34fe-47da-b5e9-f8faa23aea1c"
},
"d4d3e89f-ad51-4206-b347-e8273e2cbd78" : {
"email" : "hey#t.com",
"firstname" : "dfads",
"lastname" : "dfsda",
"uid" : "d4d3e89f-ad51-4206-b347-e8273e2cbd78"
}
}
}
And here is my Auth factory which does things like log out, store the current user profile as an object and so on.
app.factory('Auth', ['rootRef', '$firebaseObject','$firebaseAuth', function (rootRef, $firebaseObject,$firebaseAuth) {
var auth = $firebaseAuth(rootRef);
var user = new $firebaseObject;
auth.$onAuth(function (authData) {
if (authData) {
angular.copy(authData, user);
// Set the profile
user = $firebaseObject(rootRef.child('users').child(authData.uid));
user.$loaded().then(function (user) {
$window.localStorage['uid'] = user.uid.toString();
$window.localStorage['profile'] = user;
console.log('Window storage uid is' + $window.localStorage['uid']);
});
} else {
if (user!=null) {
user.$destroy();
}
}
});
return {
user: user,
login: function (user) {
return auth.$authWithPassword({
email: user.email,
password: user.password
})
},
logout: function(auth) {
return auth.$unauth;
},
signedIn: function (user) {
return !!user.provider;
}
}
}]);
What I want to do is load the profile data of the user when they log in to a profile page, so we see the first name, last name and other things we stored when they first signed in and we stored these variables in the users array.
But I am getting:
ionic.bundle.js:25642 TypeError: Cannot read property 'ref' of undefined
I previously tried to solve this problem by using $rootScope.user and by using my LoginCtrl and saying:
Auth.$onAuth(function (AuthData) {
if (AuthData === null) {
console.log("Not logged in yet");
} else {
var uid = Auth.$getAuth().uid;
var user = new Firebase(FirebaseUrl).child(users).child(uid).val();
user.$loaded().then(function (profile) {
$rootScope.user= profile;
})
});
}
}
}
And then
$scope.user = $rootScope.user;
This worked, but when I hard refreshed the browser the $rootScope object became null.
Any ideas how I can best achieve what I am trying to do, and most importantly where I should put each part of code given what my data structure?