Hitting our custom IdentityServer endpoint from your SPA

The last part of this series will cover how to hit your IdentityServer endpoint from a SPA (in my case, Angular4). The main functions you will need to implement are login, a method to store user credentials, a way to check for expired tokens, and a method for refreshing the login.

First I'll include the the login method I used:

    login(username: string, password: string): Observable<boolean> {
        var header = new Headers();
        header.append("Authorization", "Basic " + btoa("WebApp:webapp_secret"));
        header.append("Content-Type", "application/x-www-form-urlencoded");

        var postParams = "grant_type=password"
            + " username=" + encodeURIComponent(username)
            + " password=" + encodeURIComponent(password)
            + " scope=" + encodeURIComponent("Api offline_access");

        return this.http.post('/connect/token', postParams, { headers: header })
            .map((response: Response) => {
                try {
                    let jsonResponse = JSON.parse(response.text());

                    // login successful if there's a jwt token in the response
                    if (jsonResponse.access_token) {
                        this.storeUserAuthData(username, jsonResponse);
                        return true;
                    } else {
                        return false;
                    }
                } catch (error) {
                    console.log(error);
                    return false;
                }
            });
    }
    

The only downside of this function is that it doesn't use the discovery endpoint provided by IdentityServer to find the connect endpoint. If this is a big deal for you, you might want to add that functionality. Other than that it should pretty much be copy paste. Once this login is complete you'll want to store the user credentials and token expiration for use inside your app. This is performed by this.storeUserAuthData(username, jsonResponse) in the above function. You will also need a function to refresh the login.

    refreshLogin(username: string, refreshToken: string) {
        var header = new Headers();
        header.append("Authorization", "Basic " + btoa("WebApp:webapp_secret"));
        header.append("Content-Type", "application/x-www-form-urlencoded");

        var postParams = "grant_type=refresh_token"
            + "&nbps;refresh_token=" + encodeURIComponent(refreshToken)
            + " scope=Api";

        return this.http.post('/connect/token', postParams, { headers: header })
            .map((response: Response) => {
                try {
                    let jsonResponse = JSON.parse(response.text());

                    // refresh successful if there's a jwt token in the response
                    if (jsonResponse.access_token) {
                        this.storeUserAuthData(username, jsonResponse);
                        return jsonResponse.access_token;
                    } else {
                        return null;
                    }
                } catch (error) {
                    console.log(error);
                    return null;
                }
            });
    }
    

This is very similar to the login method but you're sneind the refresh token to the server instead of the password. Using these methods you can build your own way to track token expiration and refresh the user's credentials.