Asp.NET Core+ABP框架+IdentityServer4+MySQL+Ext JS之显示登录视图

在上一篇文章,完成了实体的定义,接下来要做的是定义应用服务,以便提供api接口。不过,为了更好的结合客户端,笔者决定暂时把这个工作缓一下,和客户端的改造一同进行。

新建一个名为SimpleCmsWithAbp-Client的文件夹,把SimpleCMS的Ext JS脚本复制到文件夹中。然后用Visual Studio Code打开该文件夹。使用Visual Studio Code是因为在这里不需要编写C#代码,使用vscode比使用Visual Studio方便很多。

打开文件夹后,先为vscode安装一个名为IIS Express的扩展(warren-buckley.iis-express)用来启动IIS Express。扩展安装完成后,就可在打开的文件中单击鼠标右键,在菜单中选择命令面板,就可在如下图所示的输入框中执行以下命令来启动、重新启动或停止IIS Express了:

  • IIS Express: Start Website – 启动IIS Express
  • IIS Express: Stop Website – 停止IIS Express
  • IIS Express: Restart Website – 重新启动IIS Express

由于ABP框架模版默认是使用4200端口来作为跨域访问的客户端网站端口的,因而,我们需要将当前文件夹的访问端口设置为4200。在当前文件夹下新建一个名为 .vscode 的文件夹,然后在文件夹下创建一个名为 iisexpress.json 的文件,并在里面添加以下代码:

{
    "port":4200
}

好了,现在可以启动IIS Express来访问网站了,不过执行肯定是错误的。我们先打开app.json文件,将里面的首页文件( indexHtmlPath )设置回 index.html 。然后打开index.html文件,在调用 bootstrap.js 脚本的SCRIPT标记前添加以下代码:

        var ROOTPATH = 'http://localhost:21021';
        var LOCALPATH = 'http://localhost:4200';
    

以上代码用于指定远程访问地址和本地地址。

接下来打开 apputilUrl.js ,将getResource方法修改为以下代码:

getResource: function (res) {
        var me = this;
        return LOCALPATH + '/' + me.resources[res];
    }

代码完成后按CTRL+ 打开终端窗口执行一次 sencha app build`,重建生成一次项目。现在在浏览器访问应用,会正常显示界面了,不过会提示访问错误。问题不大,接下来就是要修正这些问题。

WebApi是通过令牌认证(Token Auth)来访问的,需要在Ajax的头部添加Authorization来发送认证令牌。在修改Ajax的头部前,需要先考虑这令牌如何保存的问题。根据《 Where to Store your JWTs – Cookies vs HTML5 Web Storage 》一文,建议的方法是将令牌保存在Cookies中,但这又带来一个CORS的安全问题,需要为Ajax开启cors保护。

在研究了ABP框架模版自带的angular版本客户端的启动过程( AppPreBootstrap.ts ),会发现在提交请求时,会在Ajax的头部添加 Authorization.AspNetCore.CultureAbp.TenantId 这三个头。为了便于在Ajax请求添加这三个头,我们可在 apputil 文件夹下,新建一个名为 Headers.js 的脚本文件,然后添加以下代码:

Ext.define('SimpleCMS.util.Headers',{
    alternateClassName: 'HEADERS',
    singleton: true,

    requires:[
        'Ext.util.Cookies'
    ],

    authTokenCookieName : 'Abp.AuthToken',
    authTokenHeaderName : 'Authorization',
    tenantIdCookieName : 'Abp.TenantId',
    tenantIdHeaderName: 'Abp.TenantId',
    cultureTCookieName: 'Abp.Localization.CultureName',
    cultureHeaderName: '.AspNetCore.Culture',

    getAuthToken: function(){
        return Ext.util.Cookies.get(this.authTokenCookieName);
    },

    getTenantId: function(){
        return Ext.util.Cookies.get(this.tenantIdCookieName);
    },


    getCulture: function(){
        return Ext.util.Cookies.get(this.cultureTCookieName);
    },

    setCookies: function(name, value , expires , path , domain , secure ){
        Ext.util.Cookies.set(name, value , expires , path , domain , secure);
    },


    getHeaders: function(){
        var me = this;
        return {
            'Authorization' : 'Bearer ' +  me.getAuthToken(),
            'Abp.TenantId' : me.getTenantId(),
            '.AspNetCore.Culture' : me.getCulture()
        }
    }


});

方法getHeaders用户返回组合好的头部,还有3个get方法用于从Cookies中返回令牌、当前用户的默认语言和组合编号,setCookies方法则用于存储Cookies。添加Header类后,在app.js中添加对它的引用。

为了方便的将请求头自动写入Ajax请求的头部,而不需要每次写请求时才加入,最好的方式是重写Ext.Ajax类或在发送请求前统一处理。由于Ext.Ajax是单例模式的类,不便于重写,因而只有在发送请求前统一处理了。经过查看API,发现Ext.Ajax有 beforerequest 事件,正是所需的。接下来要考虑的是在哪里执行了。经过测试,发现在 Application.jslaunch 方法是不行,因为这时候主视图已经初始化并开始执行流程了。通过查阅Ext.app.Application的API,发现还有一个init方法,它会在主视图初始化之前执行,正是所需的。在init方法中添加以下代码:

init: function(){
        Ext.util.Format.defaultValue = function (value, defaultValue) {
            return Ext.isEmpty(value) ? defaultValue : value;
        }
        Ext.Ajax.on('beforerequest', this.onAjaxBeforeRequest, this);
        Ext.Ajax.cors = true;        
    },

在代码中,通过on方法将beforerequest事件绑定到了onAjaxBeforeRequest方法。将cors设置为true是打开Ajax的CORS防御机制。

方法 onAjaxBeforeRequest 的代码如下:

onAjaxBeforeRequest: function(conn , options , eOpts ){
        if(!options.headers) options.headers = {}
        Ext.apply( options.headers, HEADERS.getHeaders());
        options.jsonData = true;
    }

代码先判断Ajax的选项是否已包含headers的配置,如果没有,则将headers设置为一个对象,然后调用getHeaders方法将返回的头部信息通过 apply 方法复制到headers中。将jsonData设置为true是为了将提交的contentType设置为 application/json ,而不是默认的 text/plain

由于使用的是令牌认证,因而,只要验证一下Cookies中是否存在令牌,就可知道用户是否已经登录,如果没有,则显示登录页,如果有,则去获取用户信息。打开appviewmainMainController.js文件,在onMainViewRender方法中,将代码修改为以下代码:

onMainViewRender: function () {
        var me = this,
            token = HEADERS.getAuthToken();
        if (Ext.isEmpty(token)) {
            me.setCurrentView("login");
            return;
        }
    },

好了,现在可以显示登录视图了。总的感觉来说,这比原来的方式简单不少。

责编内容来自:黄灯桥的专栏 (源链) | 更多关于

阅读提示:酷辣虫无法对本内容的真实性提供任何保证,请自行验证并承担相关的风险与后果!
本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 前端开发 » Asp.NET Core+ABP框架+IdentityServer4+MySQL+Ext JS之显示登录视图

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录