JHipster一知半解- 4.6.4 webapp-shared目錄-1
迴文集目錄: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.1 webapp-目錄結構WebAPP
- 【目錄】JVM目錄JVM
- 【目錄】集合框架目錄框架
- c++ Cmake工程(1)同級目錄C++
- Oracle軟體安裝目錄資訊Inventory作用以及如何重建此目錄 - 1Oracle
- 【目錄】JUC鎖框架目錄框架
- 目錄:SpringBoot學習目錄Spring Boot
- 【一知半解】AQSAQS
- 使用jhipster搭建微服務微服務
- Nginx虛擬目錄alias和root目錄Nginx
- /opt目錄和/usr目錄的區別
- VUE - 配置根目錄(用@代表src目錄)Vue
- 【機器學習】目錄機器學習
- ORACLE目錄Oracle
- ~ 家目錄
- 目錄管理
- 活動目錄
- 目錄操作
- 電視劇目錄
- Typora 使用1之-----簡介、顯示大綱目錄
- Laravel學習路線【1】基礎目錄認識Laravel
- 儲存目錄的SMB目錄共享問題
- 刪除目錄及目錄下所有檔案與子目錄 (轉)
- DiscuzX2.5完整目錄結構【模板目錄template】
- linux 壓縮目錄並排除某個目錄Linux
- 0001-HTML中上一級目錄、上上級目錄、下一級目錄、下下級目錄中的頁面的相互引用HTML
- PHP DIY 系列------框架篇:1. 框架目錄與輔助PHP框架
- 【Linux入門教程】1 簡介、檔案管理、目錄Linux
- Express 文件(目錄)Express
- rsync 同步目錄
- redis系列目錄Redis
- 學習目錄
- CSS系列目錄CSS
- 品味FastDFS~目錄AST
- WebApi系列~目錄WebAPI
- JavaScript系列目錄JavaScript
- ORACLE directory 目錄Oracle
- excel生成目錄Excel