vuetifyjs/vuex

Access Token Retrieval

budowski opened this issue · 5 comments

Glad to see an official Vuex Cognito plugin!

As part of AWS Cognito usage, usually there are Cognito-authenticated API calls (to API Gateway, etc.).
For that, we'll need to retrieve the access token to use in the HTTP request's Authorization header.
My current implementation for that (notice that is directly relying on the AWS Cognito library + it's not promise-based):

function getAccessToken(callback) {
    const user = gUserPool.getCurrentUser();

    if (user == null) {
        callback(null, 'User not logged in');
        return;
    }

    user.getSession((err, session) => {
        if (err) {
            callback(null, err);
            return;
        }

        if (session.isValid()) {
            // Return the token
            callback(session.getIdToken().getJwtToken(), null);
            return;
        }

        // Need to refresh token
        user.refreshSession(session.getRefreshToken(), (error, newSession) => {
            if (error) {
                callback(null, error);
                return;
            }

            // Return the new token
            callback(newSession.getIdToken().getJwtToken(), null);
        });
    });
}

Or is this out of scope for the module?

But does that include the session refresh logic? Or does that save the call to getSession?

it just have plain tokens. And afaik amplify handles refreshing token in it

zaun commented

Amplify will keep the session and token updated if, and only if, you use amplify for all your API calls. If you are using amplify only for authentication, then using your own rest API backend, you'll have to keep it up to date on your own.

Using axios as an example:

axios.interceptors.request.use((config) => {
  return store.dispatch('cognito/fetchSession').then(() => {
    // User is logged in. Set auth header on all requests
    config.headers.Authorization = 'Bearer ' + store.state.cognito.session.idToken.jwtToken
    return Promise.resolve(config)
  }).catch(() => {
    // No logged-in user: don't set auth header
    return Promise.resolve(config)
  })
})

@zaun this solution is nice, however if you're running in universal mode:

In universal mode, middlewares will be called server-side once (on the first request to the Nuxt app or when page refreshes) and client-side when navigating to further routes.

Whenever you refresh the page, you'll lose the authentication because the middleware doesn't run on the client every time (reference this and this )

I noticed in example-auth0 their middleware checks for a cookie or localstorage depending on whether the code is running on server or client. Might be useful for Vuex Cognito plugin to follow a similar pattern, however if others have a better solution, would love to hear it!

Hope this helps anyone still searching for answers to why their auth doesn't seem to persist.