【问题标题】:Use the JWT tokens across multiple domains with Typescript JsonServiceClient - ServiceStack使用 Typescript JsonServiceClient 跨多个域使用 JWT 令牌 - ServiceStack
【发布时间】:2017-11-22 04:42:46
【问题描述】:

在得到this SO question 的答复后,我意识到我有一个跨域问题,即 httponly 标记的 ServiceStack BearerToken Cookie 没有发送到我在不同域上的资源微服务。

ServiceStack 的文档在其文档here 中解释了如何解决此问题。

我在实现 ServiceStack 文档中代码示例的 Typescript 版本时遇到了问题。我猜文档中的示例代码是 C#。

这是我的带有 cmets 的 Typescript 代码:

import { JsonServiceClient, IReturn } from 'servicestack-client';
import { AuthService } from './auth.service';
//dtos generated by myauthservice/types
import { GetAccessToken, ConvertSessionToToken, ConvertSessionToTokenResponse } from './dtos'
import { AppModule } from '../../app.module';
import { Router } from '@angular/router';

export class JsonServiceClientAuth extends JsonServiceClient {

    private router: Router;
    private authClient: JsonServiceClient;

    constructor(baseUrl: string) {
        console.log('JsonServiceClientAuth.baseUrl', baseUrl);
        super(baseUrl);
        //Router is not injected via the contructor because clients of JsonServiceClientAuth need to create instances of it
        this.router = AppModule.injector.get(Router);
        this.authClient = new JsonServiceClient("http://localhost:5006");

        this.onAuthenticationRequired = async () => {
            console.log('JsonServiceClientAuth.onAuthenticationRequired()');
            console.log('An API is not receiving the bearerToken being redirected to Login');
            this.router.navigate(['/login']);
        };
    }

    get<T>(request: IReturn<T> | string, args?: any): Promise<T> {
        return new Promise<T>((resolve, reject) => {

            //cross domain issue here, ss-tok httponly Cookie will not be sent to the Resource Service
            //ConvertSessionToToken per Service Stacks documentation: http://docs.servicestack.net/jwt-authprovider#converting-an-existing-authenticated-session-into-a-jwt-token

            //but send expects 2-4 argumments, one being the method name
            //the Typecript send will not use the dto ConvertSessionToToken request and get the url
            //var tokenResponse = this.send(new ConvertSessionToToken())

            console.log('this.bearToken', this.bearerToken); //undefined
            //so try JsonServiceClient.get
            this.authClient.get(new ConvertSessionToToken())
                .then(res => {
                    console.log('ConvertSessionToToken.res', res); 
                    console.log('this.bearToken', this.bearerToken); //undefined
                    //next problem there is no function getTokenCookie in Typescript that I can find, not in the dtos and not in JsonServiceClient
                    //var jwtToken = this.getTokenCookie(); //From ss-tok Cookie

                    //maybe this will work?
                    //super.setBearerToken(this.bearerToken)
                    super.get(request).then(res => {
                        console.log('suger.get.res', res);
                        resolve(res);
                    }, msg => {
                        console.log('suger.get.msg', res);
                        reject(msg)
                    })
                    .catch(ex => {
                        console.log('suger.get.ex', ex);
                        reject(ex);
                    });
                }, msg => {
                    console.log('ConvertSessionToToken.msg', msg);
                    reject(msg);
                })
                .catch(ex =>{
                    console.log('ConvertSessionToToken.ex', ex);
                    reject(ex);
                });
        });
    }

}

【问题讨论】:

    标签: typescript servicestack


    【解决方案1】:

    为什么要实现自定义 JsonServiceClient?只需在现有的 JsonServiceClient 上使用现有的 bearerTokenrefreshToken 属性,它们已经内置支持发送 JWT 不记名令牌和使用刷新令牌重新获取过期的 JWT 令牌。

    您可以查看client.auth.spec.ts 以获取支持的行为示例。

    【讨论】:

    • 我已经查看了 client.auth.spec.ts 中的所有这些测试方法,我有跨域资源 API,所以 JsonServiceClient 请求不包括 ss-tok。我没有 refreshToken,因为我使用的是自定义旧数据库,并且无法使用 Javascript 访问 httponly ss-tok。我不知道如何为已通过身份验证的用户对跨域资源 api 进行授权调用。在相当多的 client.auth.spec.ts 测试中,您要么基于模拟 userAuthId、电子邮件创建 Jwt,要么您有要授权的用户名/密码,我已经有一个 BearerToken,用户已经登录
    • 您说“您需要在服务客户端上显式设置 BearerToken”才能使我的跨域资源请求正常工作,因此我正在实施自定义 JsonServiceClient 以从我的应用程序区域隐藏这些实施细节使用 JsonServiceClient
    • 查看我的updated answer with the new IUserSessionSource,它可以让您在没有 AuthRepository 的情况下使用 RefreshTokens。但这与此无关,您不能在跨域的令牌 Cookie 中使用 JWT,但您可以使用 bearerToken 属性,该属性使用授权 HTTP 标头发送令牌。所以不要设置UseTokenCookie=true 然后access the BearerToken from the AuthenticateResponse 并使用它来填充每个不同的JsonServiceClient 实例。
    • 我应该将 AuthenticateResponse 的 BearerToken 属性值存储在 cookie 中吗?我很快就没有用户名/密码,所以我不能继续调用 authClient.Send(new Authenticate()).BearerToken;每次我明显地创建一个新的 JsonServiceClients 时。
    • @BrianOgden 不,不要使用 cookie,只需填充每个 JsonServiceClientbearerToken 属性,然后为每个不同的站点重用实例。
    猜你喜欢
    • 2019-02-17
    • 2017-07-02
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 2022-06-28
    • 2021-08-19
    • 2016-12-29
    • 1970-01-01
    相关资源
    最近更新 更多