Base solution for your next web application
Open Closed

Expired user session causes odd LogOut behavior #11708


User avatar
0
henriksorensen created

Error message with the inability to log out

We encountered an error when the user's session has expired and the user is trying to log out of the site. It leads to an error message with the inability to log out.

Pre-conditions: User session is expired (AccessTokenExpirationMinutes parameter is used to set session timeout)

Debug steps:

  1. User clicks Logout button

  2. From angular project, the GET request is sent to back-end Logout endpoint - /api/TokenAuth/LogOut Original ASP NET Zero code: logout(reload?: boolean, returnUrl?: string): void { let customHeaders = { [abp.multiTenancy.tenantIdCookieName]: abp.multiTenancy.getTenantIdCookie(), Authorization: 'Bearer ' + abp.auth.getToken(), };

     XmlHttpRequestHelper.ajax(
         'GET',
         AppConsts.remoteServiceBaseUrl + '/api/TokenAuth/LogOut',
         customHeaders,
         null,
         () => {
             abp.auth.clearToken();
             abp.auth.clearRefreshToken();
             new LocalStorageService().removeItem(AppConsts.authorization.encrptedAuthTokenName, () => {
                 if (reload !== false) {
                     if (returnUrl) {
                         location.href = returnUrl;
                     } else {
                         location.href = '';
                     }
                 }
             });
         }
     );
    

    }

  3. This endpoint looks like: Original ASP NET Zero code:

     [HttpGet]
     [AbpMvcAuthorize]
     public async Task LogOut()
     {
         if (AbpSession.UserId != null)
         {
             var tokenValidityKeyInClaims = User.Claims.First(c => c.Type == AppConsts.TokenValidityKey);
             await RemoveTokenAsync(tokenValidityKeyInClaims.Value);
    
             var refreshTokenValidityKeyInClaims =
                 User.Claims.FirstOrDefault(c => c.Type == AppConsts.RefreshTokenValidityKey);
             if (refreshTokenValidityKeyInClaims != null)
             {
                 await RemoveTokenAsync(refreshTokenValidityKeyInClaims.Value);
             }
    
             if (AllowOneConcurrentLoginPerUser())
             {
                 await _securityStampHandler.RemoveSecurityStampCacheItem(
                     AbpSession.TenantId,
                     AbpSession.GetUserId()
                 );
             }
         }
     }
    
  4. The main problem is with the AbpMvcAuthorize attribute [AbpMvcAuthorize] Since user is already not authenticated, then it leads to 404 response from server(suggest, one more error in ASP NET Zero, it should be 401).

  5. On front-end part this response is handled as:

export class XmlHttpRequestHelper { static ajax(type: string, url: string, customHeaders: any, data: any, success: any) { let xhr = new XMLHttpRequest();

    xhr.onreadystatechange = () => {
        if (xhr.readyState === XMLHttpRequest.DONE) {
            if (xhr.status === 200) {
                let result = JSON.parse(xhr.responseText);
                success(result);
            } else if (xhr.status !== 0) {
                alert(abp.localization.localize('InternalServerError', 'AbpWeb'));
            }
        }
    };

    url += (url.indexOf('?') >= 0 ? '&' : '?') + 'd=' + new Date().getTime();
    xhr.open(type, url, true);

    for (let property in customHeaders) {
        if (customHeaders.hasOwnProperty(property)) {
            xhr.setRequestHeader(property, customHeaders[property]);
        }
    }

    xhr.setRequestHeader('Content-type', 'application/json');
    if (data) {
        xhr.send(data);
    } else {
        xhr.send();
    }
}

}

Alert message is shown:

alert(abp.localization.localize('InternalServerError', 'AbpWeb'));

Expected result Alert Internal Server Error message

Actual result No errors, user is logged out, login page is displayed

Question

Do you agree that the expected result is not as desired? Will you fix this in a later release? (we are using 11.4)


1 Answer(s)