I have a login system where I need to keee the logged in user on localstorage, and once the user logs I want to redirect him to his own page whenever he accesses the login page.
My template:
<iron-localstorage name="user-storage" value="{{storedUser}}"></iron-localstorage>
My object:
static get properties() {
return {
storedUser: {
type: Object,
notify: true
},
...
}
}
I want to do this:
redirect() {
console.log(this.storedUser);
if(this.storedUser) {
// Redirect user or admin to their own homescreen
if(this.storedUser.role == 'user')
this.set('route.path', '/homescreen-usuario');
else if(this.storedUser.role == 'admin')
this.set('route.path', '/homescreen-admin');
else
this.set('route.path', '/my-view404');
}
}
But the first line always logs "undefined".
You should use the 'on-iron-localstorage-load-empty' and 'on-iron-localstorage-load' events to react to the storage events, or you can use an observer on your 'storedUser' property.
Related
i am required to make Register And Login process by connecting Ionic 4 to MySQL, the Login and Registration works, but i am having problem on configuring the guard to enable access based on user currently logged in, below is my code at tabs.router.module.ts which is the route for first loaded page after user logged in
{
path: 'profile-qr',
children: [
{
path: '',
loadChildren: () =>
import('../profile-qr/profile-qr.module').then(m => m.ProfileQRPageModule),
canActivate: [AuthGuard],
data: {
role: 'C'
}
}
]
},
below is my code to store login data in local storage during login process login.page.ts
async prosesLogin(){
if(this.loginForm.value.email != "" && this.loginForm.value.password != ""){
let body = {
email: this.loginForm.value.email,
password: this.loginForm.value.password,
action: 'login'
};
this.postPvdr.postData(body, 'user-api.php').subscribe(async data =>{
if(data.success){
this.storage.set('session_storage', data.result);
below is my code at AuthGuard auth.guard.ts
canActivate(route: ActivatedRouteSnapshot){
const expectedRole = route.data.role;
this.storage.get('session_storage').then((res)=>{
if (res == null){
this.router.navigate([`/home`]);
return false;
}else{
if (expectedRole == res.role) {
return true;
} else {
this.router.navigateByUrl('/login');
return false;
}
}
})
return false;
}
during login as customer#email.com which have a role of 'C' which is customer, i am unable to access any page which have set canActivate : [AuthGuard]
i have tried to copy other code style, which use Observable and Firebase, but i am unable to do so with MySQL because i do not really understand how to write Observable object.
i have checked on the mysql database and the user role are inserted correctly, there are no problem appear on my VSCode,
the problem are only at RBAC
kindly guide and explain on how to write code at auth.guard.ts
i want to show a message in my authentification page when my token expires.
the app has a guard that checks in every request if user is still authenticated or not(token is still valid or not).
my problem is when i used localstorage and session storageto store the variable "expired". expired has always true since it's stored in the navigator. Any other solutions?
I am new to angular so please any help ?
what i want to show in my login page if expired is true:
<span *ngIf="expired" class="help-block text-danger">
Votre session a expiré !
</span>
and here is the guard code :
#Injectable()
export class AuthGuard implements CanActivateChild {
constructor(private router: Router, private localSt:
LocalStorageService, private loginService: LoginService) {
}
canActivateChild(childRoute: ActivatedRouteSnapshot, state:
RouterStateSnapshot) {
if (this.loginService.isAuthenticated()) {
sessionStorage.setItem("expired", 'false');
return true;
}
sessionStorage.setItem("expired", 'true');
this.router.navigate(['/login']);
return false;
}
}
what I do to show "The session has expired" is:
If the user is idle, or navigating to a URL without the proper permissions I send him/her to the login page through a function on a shared service
endSesion( message ) {
window.localStorage.clear(); //to clear all session variables, tokens and stuff
window.localStorage.setItem('message',message) // save as the only left thing in LS
this.router.navigate(['login']);
}
And in the constructor or the ngOnInit of the login component
ngOnInit() {
this.message = window.localStorage.getItem('message'); // get the message from LS
if ( this.message ) {
alert('Dude!: ' + this.message ); //maybe sweetalert will be nicer to look at
}
}
This way you dont only use to throw user out beacuse a session expired but maybe if not permission or maybe if you check another security issue even froma backend response.
I would like to make sure that only the socket which sends a registration / "users create" message gets the according "users created" response. There is a simple example for that in the documentation looking like this:
// Publish the `created` event to admins and the user that sent it
app.service('users').publish('created', (data, context) => {
return [
app.channel('admins'),
app.channel(app.channels).filter(connection =>
connection.user._id === context.params.user._id
)
];
});
However this is not working for me. If I log the context.params object, this simply looks like this when registering a new user:
{ query: {},
route: {},
connection: { provider: 'socketio' },
provider: 'socketio' }
Accordingly, the appropriate connection does not get the event. Am I missing something here? Do I have to add something in the registration process for this to work? Thanks a lot!
The easiest solution would be to not worry about dispatching the real-time event to that user at all. If the same connection is already calling .create the result from that promise (.create(data).then(userData => {})) will be the same as the dispatched event.
If you'd still like to have a newly created user join certain channels you can use params.connection in an after hook as shown in this issue:
app.service('users').hooks({
after: {
create(context) {
const { params: { connection }, result } = context;
if(connection) {
context.app.channel(`user/${result.id}`).join(connection);
}
return context;
}
}
});
I created a simple login page using extjs MVC to understand MVC architecture of extjs. As you can see below, I am trying to get the json data into the store and then I will check each username and password in that data with the entered login credentials. The thing in which I am confused right now is that, how to check the username and password from the retrieved json data present in store folder into the view folder? (Below code is only the related code with the problem)
I aware that this could invoke security threats, as I am checking on client side.
'view' folder --> Code.js
function checkJson(username, password){
//if matched, return true.
//else, return false.
}
'model' folder --> Code.js
Ext.define('AM.model.User', {
extend: 'Ext.data.Model',
fields: ['name', 'email']
});
'store' folder --> Code.js
Ext.define('LoginPage.store.Code', {
extend: 'Ext.data.Store',
model: 'LoginPage.model.Code',
autoLoad: true,
proxy: {
type: 'ajax',
api: {
read: 'data/loginResponse.json',
update: 'data/checkCredentials.json' //Contains: {"success": true}
},
reader: {
type: 'json',
root: 'loginResponse',
successProperty: 'success'
}
}
});
loginResponse.json
{
"form": {
"login": [
{
"username": "venkat",
"password": "123"
},
{
"username": "admin",
"password": "345"
}
]
}
You should put your checking part of the code to the Controller (views are for presentation). In view define some form with login and password fields. In Controller catch click event on form OK (Login) button, get form values (login + password), then use Ext.data.Store.query() method to find wether credentials fits or not like:
Look here for examples how to use controllers in MVC to catch events;
In your Controller put:
init: function() {
this.control({
'#form_ok_button': { // this is the `id` property of your form's Login button
click: function(button) {
var fValues = button.up('form').getValues(); // Assume your button is bound to the form
// Or you can use `Controller.refs` property (http://docs.sencha.com/ext-js/4-1/#!/api/Ext.app.Controller-cfg-refs) to get form
var matched = store.query('username', fValues.username);
if(matched.length && matched[0].get('password') === fValues.password) {
// login OK!
}
}
}
});
},
How to use refs (in Controller):
refs: [
{ ref: 'usernameField', selector: '#username_field' }, // username field id is "username_field"
{ ref: 'passwordField', selector: '#password_field' }, // password field id is "password_field"
],
init: function() {
this.control({
'#form_ok_button': {
click: function() {
// with `refs` autogetters are created for every `ref`:
var username_field = this.getUsernameField();
var password_field = this.getPasswordField();
}
}
})
}
You can read about referencing here.
For every Store in Ext.app.Controller.stores array autogetters are created too (in your case for Code store use this.getCodeStore() inside controller).
Here is the flow:
You get username and password field values with this.getUsernameField() and this.getPasswordField();
You query() store for username
If username exist in store, you check if password fits.
I am using connect-mysql-session to store sessions in db. Now my question is how do i add user data containing browser agent and ip-adress to check if the session is valid? How do i obtain that information? And how do i check if it matches?
users.login(credentials,function(err, results) {
//On errors
if (err) {
res.render(routes.index, {
title: 'Login'
});
//On success
} else if (results[0]) {
//Set session data and redirect to start page
req.session.userdata = results[0];
req.session.userdata.email = req.body.email_login;
req.session.is_logged_in = true;
res.redirect('/start');
//Wrong credentials
} else {
req.flash('warning','Wrong password or login');
res.render('index', {
title: 'Login'
});
}
});
Update:
I now got this added to the session:
req.session.ip = req.connection.remoteAddress;
req.session.useragent = req.headers['user-agent'];
and check for it in my auth middleware:
if(req.session.userdata && req.session.is_logged_in === true && req.session.ip === req.connection.remoteAddress && req.session.useragent === req.headers['user-agent']) {
next();
} else {
res.redirect('/');
}
Is this secure or do you see any risks with this? Should i go about it another way?
Your implementation looks good, and will give you some - very - basic protection against session hijacking.
However, I'm not sure I understand your middleware. What prevents an user from requesting /start directly? And, more importantly, as the middleware intercepts all requests, even those for /start, doesn't this look like some infinite redirect loop?
My suggestion would simply be to consider a user logged out at all time when ip or user agent mismatches.