美文网首页
JHipster一知半解- 4.6.4 webapp-share

JHipster一知半解- 4.6.4 webapp-share

作者: 沉寂之舟 | 来源:发表于2018-06-13 21:11 被阅读55次

    回文集目录:JHipster一知半解

    shared.module.ts

    SharedModule整合了Lib模块,Common模块两个子模块的内容,并且重新导出,作为整个的共享模块(工具模块)使用。

    @NgModule({
        //引入两个子模块
        imports: [
            JhipsterSampleApplicationNg2SharedLibsModule,
            JhipsterSampleApplicationNg2SharedCommonModule
        ],
        //声明自己的组件,指令
        declarations: [
            JhiLoginModalComponent,
            HasAnyAuthorityDirective
        ],
        //声明通用的服务,主要,由于不是在主模块provider了,只有引入SharedModule的才能使用这些
        //实际上,其他所有的子模块都有引入SharedLibsModule。
        providers: [
            LoginService,
            LoginModalService,
            AccountService,
            StateStorageService,
            Principal,
            CSRFService,
            AuthServerProvider,
            UserService,
            DatePipe
        ],
        //模块的入口组件--SharedModule并不会被路由懒加载到,所有声明并没有意义
        entryComponents: [JhiLoginModalComponent],
        exports: [
            JhipsterSampleApplicationNg2SharedCommonModule,
            JhiLoginModalComponent,
            HasAnyAuthorityDirective,
            DatePipe
        ],
        //语言模式,CUSTOM_ELEMENTS_SCHEMA是angular提供的一种模式,允许在命名时使用“-”。
        /* Defines a schema that will allow:
        * - any non-Angular elements with a `-` in their name,
        * - any properties on elements with a `-` in their name which is the common rule for custom elements.
        */
        schemas: [CUSTOM_ELEMENTS_SCHEMA]
    
    })
    export class JhipsterSampleApplicationNg2SharedModule {}
    

    shared-libs.module.ts

    @NgModule({
        imports: [
            NgbModule.forRoot(),
            NgJhipsterModule.forRoot({
                // set below to true to make alerts look like toast
                alertAsToast: false,
                i18nEnabled: true,
                defaultI18nLang: 'en'
            }),
            InfiniteScrollModule,
            CookieModule.forRoot()
        ],
        exports: [
            FormsModule,
            HttpModule,
            CommonModule,
            NgbModule,
            NgJhipsterModule,
            InfiniteScrollModule
        ]
    })
    export class JhipsterSampleApplicationNg2SharedLibsModule {}
    

    SharedLibsModule比较简单,引用了NgbModule,NgJhipsterModule,InfiniteScrollModule,CookieModule,并且初始化了它们,重新导出了它们。
    值得主要的是,这里是初始化ng-jhipster的地方,参见
    TODO:链接ng-jhipster源码1-顶层

    shared-common.module.ts

    定义了内部(JHipster)实现的语言帮助(显示Title),警告组件两个部分,
    奇怪的是,有的组件是放Shared顶层的,有的又放到Common里面,是因为语言帮助和警告框更有通用性吧

    alert目录

    JhiAlertErrorComponent和JhiAlertComponent两个组件的外观(template)是一直的,但是内部逻辑有所区别。JhiAlertComponent就完全依赖alertService,使用服务进行显示提示框。
    则在JhiAlertErrorComponent在自己内部保存alert数组(也依赖alertService构造),并且通过cleanHttpErrorListener注册监听httpError的错误,通过异步的方式在compont里面进行通讯错误的提示。

    auth目录

    account.service.ts

    @Injectable()
    export class AccountService  {
        //这里注入的http是Jhipster修改过的。
        constructor(private http: Http) { }
        //调用Restful接口获取用户数据,返回一个any型,比较宽松
        get(): Observable<any> {
            return this.http.get(SERVER_API_URL + 'api/account').map((res: Response) => res.json());
        }
        //调用Restful保存获取用户数据
        save(account: any): Observable<Response> {
            return this.http.post(SERVER_API_URL + 'api/account', account);
        }
    }
    

    auth-jwt.service.ts

    在Shared内部使用的登录辅助类,JWT认证方式时候的通讯类。

        //传入凭证信息,进行登录认证通讯
        login(credentials): Observable<any> {
            //post内容,用户名,密码,是否记住
            const data = {
                username: credentials.username,
                password: credentials.password,
                rememberMe: credentials.rememberMe
            };
            //这里调用api/authenticate认证,
            return this.http.post(SERVER_API_URL + 'api/authenticate', data).map(authenticateSuccess.bind(this));
    
            function authenticateSuccess(resp) {
                //登录成功从返回报文头获取Authorization,并且使用魔数“Bearer ”分隔。
                const bearerToken = resp.headers.get('Authorization');
                if (bearerToken && bearerToken.slice(0, 7) === 'Bearer ') {
                    const jwt = bearerToken.slice(7, bearerToken.length);
                    this.storeAuthenticationToken(jwt, credentials.rememberMe);
                    return jwt;
                }
            }
        }
        //另外一种登录方式,仅保存的jwt信息,无需特别通讯(在每次通讯的报文头都会带上jwt的token信息)
        loginWithToken(jwt, rememberMe) {
            if (jwt) {
                this.storeAuthenticationToken(jwt, rememberMe);
                return Promise.resolve(jwt);
            } else {
                return Promise.reject('auth-jwt-service Promise reject'); // Put appropriate error message here
            }
        }
        //根据rememberMe的值,决定是保存到$localStorage还是$sessionStorage
        storeAuthenticationToken(jwt, rememberMe) {
            if (rememberMe) {
                this.$localStorage.store('authenticationToken', jwt);
            } else {
                this.$sessionStorage.store('authenticationToken', jwt);
            }
        }
        //无http操作,仅清空本地存储的token即可
        logout(): Observable<any> {
    
            return new Observable((observer) => {
                this.$localStorage.clear('authenticationToken');
                this.$sessionStorage.clear('authenticationToken');
                observer.complete();
            });
        }
    

    其中$localStorage和$sessionStorage是由ngx-webstorage(之前是ng2-webstorage)提供的浏览器端存储服务,顾名思义可知,API调用方法相同,存储的位置,有效期不同。

    csrf.service.ts

    从cookie中获取XSRF-TOKEN的值。
    

    has-any-authority.directive.ts

    通过判断权限列表,决定页面某个标签是否显示。通过注入principal进行判断。其判断有点类似ngif的指令,根据输入的值,调用viewContainerRef重新绘制页面。
    

    P.S Jhipster的权限控制,大都是Hard code近代码的,比较简单,动态性小。

    principal.service.ts

    核心的服务,保存用户的认证信息,用户名,是否认证,认证状态主题(Subject),核心代码为几个用户权限的判断hasAnyAuthority(hasAnyAuthority,hasAnyAuthorityDirect,hasAuthority),以及用户状态的判断isAuthenticated。
    

    state-storage.service.ts

    constructor(
            private $sessionStorage: SessionStorageService
        ) {}
    

    在构造器中注入$sessionStorage,用来在URL跳转中能记录状态。主要包括previousState,destinationState,previousUrl三种信息。其中previousState包含name和params两个内容。

    storePreviousState(previousStateName, previousStateParams) {
            const previousState = { 'name': previousStateName, 'params': previousStateParams };
            this.$sessionStorage.store('previousState', previousState);
        }
    

    destinationState包含目标状态destinationState,目标参数destinationStateParams,目标来源fromState三个内容

    storeDestinationState(destinationState, destinationStateParams, fromState) {
            const destinationInfo = {
                'destination': {
                    'name': destinationState.name,
                    'data': destinationState.data,
                },
                'params': destinationStateParams,
                'from': {
                    'name': fromState.name,
                }
            };
            this.$sessionStorage.store('destinationState', destinationInfo);
        }
    

    user-route-access-service.ts

    它是一个路由守卫CanActivate,用来控制能否进行url跳转,进入某个页面,核心方法为canActivate,调用checkLogin进行验证
    
    checkLogin(authorities: string[], url: string): Promise<boolean> {
            const principal = this.principal;
            //返回一个Promise对象
            return Promise.resolve(principal.identity().then((account) => {
                //判断要求的权限列表,为空直接放行
                if (!authorities || authorities.length === 0) {
                    return true;
                }
                //如果登录情况,调用principal是否具有权限
                if (account) {
                  return principal.hasAnyAuthority(authorities).then(
                    (response) => {
                      if (response) {
                        return true;
                      }
                      return false;
                    }
                  );
                }
                //登记当前url,调用stateStorageService存储当前url,并且通过loginModalService显示登录框给用户登录。
                this.stateStorageService.storeUrl(url);
                this.router.navigate(['accessdenied']).then(() => {
                    // only show the login dialog, if the user hasn't logged in yet
                    if (!account) {
                        this.loginModalService.open();
                    }
                });
                return false;
            }));
        }
    

    相关文章

      网友评论

          本文标题:JHipster一知半解- 4.6.4 webapp-share

          本文链接:https://www.haomeiwen.com/subject/hpuseftx.html