首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Microsoft处理HTTP401- ServiceStack类型记录客户机

Microsoft处理HTTP401- ServiceStack类型记录客户机
EN

Stack Overflow用户
提问于 2018-04-12 22:31:17
回答 1查看 353关注 0票数 2

Using the [ServiceStack Typescript client][1] and ServiceStack Auth on the backend I am seeing a failure to call/access-在Microsoft中接收HTTP401响应的初始API请求之后的令牌。

Microsoft似乎可以处理HTTP异常和ServiceStack客户端从来没有得到“通知”(通知是401结果),因此也就没有机会在再次尝试ServiceStack请求之前处理401响应并调用<my_servicestack_api_auth_url>/access-token获取承载令牌。

您可以在Chrome中看到过滤的网络堆栈请求:

现在查看Microsoft Edge中的筛选网络堆栈:

这里是Microsoft控制台窗口:

您可以看到,在Microsoft中,在对初始请求的401个响应之后,从未发出任何<my_servicestack_api_auth_url>/access-token请求。

是否可能ServiceStack没有向<my_servicestack_api_auth_url>/access-token发出请求,然后由于Microsoft处理了401错误本身而没有重新尝试初始<my_servicestack_api_auth_url>/access-token请求?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-19 00:13:43

我扩展了服务平台-客户以封装处理异常、令牌存储和拒绝。在我的异常处理程序中,我没有重新抛出异常(虽然这只在边缘中有副作用,而不是Chrome或IE11),因此隐藏了实际的错误,即这里

代码语言:javascript
复制
import { JsonServiceClient, IReturn, ErrorResponse } from '@servicestack/client';
//service
import { AuthService } from './api/auth.service';
import { SpinnerService } from '../spinner/spinner.service';
//dtos
import { GetAccessToken, ConvertSessionToToken, ConvertSessionToTokenResponse } from './api/dtos'
import { AppModule } from '../../app.module';
import { Router } from '@angular/router';
import { TokenService } from './token.service';
import { ApiHelper } from '../api/api.helper';
import { AppRoutes } from '../const/routes/app-routes.const';

export class JsonServiceClientAuth extends JsonServiceClient {

    private router: Router;
    private tokenService: TokenService;
    private apiHelper: ApiHelper;
    private spinnerService: SpinnerService;

    constructor(baseUrl: string) {
        super(baseUrl);

        //Router, TokenService, ApiHelper are not injected via the contructor because clients of JsonServiceClientAuth need to create instances of it as simple as possibl
        this.router = AppModule.injector.get(Router);
        this.tokenService = AppModule.injector.get(TokenService);
        this.apiHelper = AppModule.injector.get(ApiHelper);
        this.spinnerService = AppModule.injector.get(SpinnerService);

        //refresh token 
        //http://docs.servicestack.net/jwt-authprovider#using-an-alternative-jwt-server
        this.refreshTokenUri = this.apiHelper.getServiceUrl(this.apiHelper.ServiceNames.auth) + "/access-token";

        this.onAuthenticationRequired = async () => {
            this.redirectToLogin();
        };
    }

    get<T>(request: IReturn<T> | string, args?: any): Promise<T> {
        this.prepareForRequest();

        let promise = new Promise<T>((resolve, reject) => {
            super.get(request)
                .then(res => {
                    this.handleSuccessfulResponse();
                    resolve(res);
                }, msg => {
                    this.handleCompletion();
                    this.handleRejection(msg);
                    reject(msg);
                })
                .catch(ex => this.handleCompletion(ex))
        });

        return promise;
    }

    post<T>(request: IReturn<T>, args?: any): Promise<T> {
        this.prepareForRequest();

        let promise = new Promise<T>((resolve, reject) => {
            super.post(request)
                .then(res => {
                    this.handleSuccessfulResponse();
                    resolve(res);
                }, msg => {
                    this.handleCompletion();
                    this.handleRejection(msg);
                    reject(msg);
                })
                .catch(ex => this.handleCompletion(ex))
        });

        return promise;
    }

    put<T>(request: IReturn<T>, args?: any): Promise<T> {
        this.prepareForRequest();

        let promise = new Promise<T>((resolve, reject) => {
            super.put(request)
                .then(res => {
                    this.handleSuccessfulResponse();
                    resolve(res);
                }, msg => {
                    this.handleCompletion();
                    this.handleRejection(msg);
                    reject(msg);
                })
                .catch(ex => this.handleCompletion(ex))
        });

        return promise;
    }

    delete<T>(request: IReturn<T>, args?: any): Promise<T> {
        this.prepareForRequest();

        let promise = new Promise<T>((resolve, reject) => {
            super.delete(request)
                .then(res => {
                    this.handleSuccessfulResponse();
                    resolve(res);
                }, msg => {
                    this.handleCompletion();
                    this.handleRejection(msg);
                    reject(msg);
                })
                .catch(ex => this.handleCompletion(ex))
        });

        return promise;
    }

    private handleRefreshTokenException() {
        this.redirectToLogin();
    }

    private handleCompletion(ex: any = null) {
        //hide spinner in case it was showing
        this.spinnerService.display(false);
        if(ex) {
            console.log('JsonServiceClientAuth.handleCompletion: rethrowing exception', ex);
            throw ex;
        }
    }

    private handleRejection(msg: any) {
        if (msg == "TypeError: Failed to fetch"){
            console.error('Failed to fetch: IT IS QUITE POSSIBLE THAT THE API YOU ARE CALLING IS DOWN');
        } 

        if(msg.responseStatus && msg.responseStatus.errorCode === "401"){
            //an API has rejected the request
            console.log('JsonServiceClientAuth.handleRejection: API returned 401 redirect to not authorized');
            this.router.navigate(['/', AppRoutes.NotAuthorized]);
        }

        if (msg.type === "RefreshTokenException") {
            console.log('JsonServiceClientAuth.handleRejection: there was a token refresh exeception');
            this.handleRefreshTokenException();
        }
    }

    private redirectToLogin() {
        this.router.navigate(['/', AppRoutes.Login], { queryParams: { redirectTo: this.router.url } });
    }

    /**
     * cross domain resources require that we explicity set the token in ServiceStack JsonServiceClients
     * https://stackoverflow.com/questions/47422212/use-the-jwt-tokens-across-multiple-domains-with-typescript-jsonserviceclient-s
     */
    private prepareForRequest() {
        //console.log('JsonServiceClientAuth.prepareForRequest');
        //console.log('this.tokenService.refreshToken', this.tokenService.refreshToken);
        this.refreshToken = this.tokenService.refreshToken;
        this.bearerToken = this.tokenService.bearerToken;
    }

    /**
     * refresh the bearer token with the latest data, every request is passed with the refresh token and the freshest bearerToken will be
     * returned with every response
     */
    private handleSuccessfulResponse() {
        //console.log('JsonServiceClientAuth.handleSuccessfulResponse');
        //console.log('this.bearerToken', this.bearerToken);
        //this will update the client side bearerToken, keeping it fresher - Ogden 4-18-2018
        this.tokenService.bearerToken = this.bearerToken;
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49806794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档