User authentication SqlStorage and web API


#1

Hi!

Here’s my issue. I’m trying to find the best way to handle this.

I have my back-end which is an API that communicates with my SQL database. When I login I query my API to get validate user/password and return a JWT token. I store this token inside SqlStorage on device. All of this works perfectly!

My main problem is what is the best practice to validate that the user is still logged in to hide/show some stuff like menu items. I tried few thing but I’m not 100% convinced is the best approach.

I would like to have a function that return true/false if the user is logged in or not to use it with a *ngIf for example. Because right now if I query the sqlstorage that return a promise so I can’t use it inside *ngIf. From what I’ve tried right now when I login I can successfully insert my data in my sqlstorage and set my loggedIn property to true inside my auth-service. But when I leave the page and come back (from browser) it’s set back to it’s default value.

Also how would you handle the loggedIn thingy? I don’t want to kick out (logout) the user if for some reason the token is expired.

auth-service.ts

constructor(private http: Http, private platform: Platform) {
        this.platform = platform;
        this.platform.ready().then(() => {
            this.storage = new Storage(SqlStorage);
        });
        this.http = http;
    }
.......................
login(loginData) {
        return new Promise(resolve => {
            this.http.post(this.baseUrl + 'Login', JSON.stringify(loginData), {headers: ApiHeaders})
            .subscribe(response => {
                var data = response.json();
                console.log("login reponse", data);
                if(data.Result) {
                    console.log("loggedin", data);
                    this.authSuccess(data.TokenValue);
                }
                resolve(data);
            },
            error => {
                console.log("error login", error);
                resolve(false);
            });
        });
    }
....................
authSuccess(token) {
        this.storage.query("INSERT INTO Auths (userId, authToken) VALUES ("+this.jwtHelper.decodeToken(token).UserId+", '"+token+"')").then(data => {
            console.log("inserted", data.res);
            this.userId = this.jwtHelper.decodeToken(token).UserId;
            this.loggedIn = true;
        }, error => {
            console.log("error", error);
        });
    }
......................
logout() {
        return new Promise(resolve => {
            console.log("userid logout", this.userId);
            this.storage.query("DELETE FROM Auths WHERE userId="+this.userId).then(data => {
                console.log("deleted", data.res);
                this.userId = null;
                this.loggedIn = false;
                resolve(true);
            }, error => {
                console.log("error", error);
                resolve(false);
            });
        });
    }

I hope I’m clear enough and can’t wait to see your solutions!

Thanks a lot!


#2

These two things seem to be in conflict for me. I think you should kick the user out if the token is expired: that’s the entire point of having tokens expire.

That being said, my preferred approach here is to have a service that can be injected everywhere. It can retrieve tokens from storage, or accept tokens that are returned from a backend from a login page, for example. It retains the token, so there are no promise issues. During the window when the token has not yet been retrieved, the user is marked as not logged in. Personally, I don’t consider that a problem.

That being said, if all you’re concerned about is ngIf, you could consider using the AsyncPipe.


#3

Thanks for your response! You’re right I might have mixed things up about the token expiration thing. What I was trying to say is that I want to be able to update the token app-side when request are made to my API because I’m updating the expiration date of the token server-side because I know that if the user makes request then I need to keep him logged in.

With that said, thanks for you help! If I understand well what you just said is that you would store the token inside the service so I can use it to see if the user is still logged in? When I load the app I can make a request to my localstorage and get the token to be stored inside the service and then use everywhere else I need it. It might have a delay while making the request and putting the value inside the service but I think there’s no other way.

If that’s what you meant I think that makes total sense. I just read about async pipe and I don’t think that a good solution. I think I’ll go forward with your idea. I just want to do it the proper way when my app is loaded.

Thanks a lot!


#4

Yes, I think you’re on the right track and good luck.