1概要
このクイックチュートリアルでは、AngularJSの代わりにAngular 4を使用するために、既存のAngularアプリケーションリンク(/rest-api-spring-oauth2-angularjs)をアップグレードします。
2セットアップAngular 4
まず、フロントエンドモジュールの生成と管理にhttps://cli.angular.io/[Angular CLI]を使用します。
-
まず、https://nodejs.org/en/download/[node and npm]** をインストールします - Angular CLIはnpmツールです。
それから、Mavenを使ったAngularプロジェクトを構築するには、https://github.com/eirslett/frontend-maven-plugin[ frontend-maven-plugin ]を使用する必要があります。
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
<nodeVersion>v6.10.2</nodeVersion>
<npmVersion>3.10.10</npmVersion>
<workingDirectory>src/main/resources</workingDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
</execution>
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
そして最後に、Angular CLIを使用して** 新しいモジュールを生成します。
ng new oauthApp
フロントエンドモジュールが2つあります。1つはパスワードフロー用、もう1つは暗黙的フロー用です。
次のセクションでは、各モジュールのAngularアプリロジックについて説明します。
3 Angular 4 を使用したパスワードフロー
次に、パスワードフローフロントエンドモジュールのロジックについて説明しましょう。
3.1. アプリサービス
app.service.ts にある AppService から始めましょう。これにはサーバーとのやり取りのロジックが含まれています。
-
obtainAccessToken() :与えられたユーザー資格情報のアクセストークンを取得する
-
saveToken() :ng2-cookiesを使ってクッキーにアクセストークンを保存する
としょうかん ** getResource() :IDを使ってサーバからFooオブジェクトを取得する
-
checkCredentials() :ユーザがログインしているかどうかを確認する
-
logout() :アクセストークンcookieを削除し、ユーザをログアウトさせる
export class Foo {
constructor(
public id: number,
public name: string) { }
}
@Injectable()
export class AppService {
constructor(
private __router: Router, private __http: Http){}
obtainAccessToken(loginData){
let params = new URLSearchParams();
params.append('username',loginData.username);
params.append('password',loginData.password);
params.append('grant__type','password');
params.append('client__id','fooClientIdPassword');
let headers = new Headers({'Content-type': 'application/x-www-form-urlencoded; charset=utf-8', 'Authorization': 'Basic '+btoa("fooClientIdPassword:secret")});
let options = new RequestOptions({ headers: headers });
this.__http.post('http://localhost:8081/spring-security-oauth-server/oauth/token', params.toString(), options)
.map(res => res.json())
.subscribe(
data => this.saveToken(data),
err => alert('Invalid Credentials'));
}
saveToken(token){
var expireDate = new Date().getTime() + (1000 ** token.expires__in);
Cookie.set("access__token", token.access__token, expireDate);
this.__router.navigate(['/']);
}
getResource(resourceUrl) : Observable<Foo>{
var headers = new Headers({'Content-type': 'application/x-www-form-urlencoded; charset=utf-8', 'Authorization': 'Bearer '+Cookie.get('access__token')});
var options = new RequestOptions({ headers: headers });
return this.__http.get(resourceUrl, options)
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
checkCredentials(){
if (!Cookie.check('access__token')){
this.__router.navigate(['/login']);
}
}
logout() {
Cookie.delete('access__token');
this.__router.navigate(['/login']);
}
}
3.2. ログインコンポーネント
次に、ログインフォームを担当する LoginComponent を見てみましょう。
@Component({
selector: 'login-form',
providers:[AppService],
template: `<h1>Login</h1>
<input type="text"[(ngModel)]="loginData.username"/>
<input type="password" [(ngModel)]="loginData.password"/>
<button (click)="login()" type="submit">Login</button>`
})
export class LoginComponent {
public loginData = {username: "", password: ""};
constructor(private __service:AppService) {}
login() {
this.__service.obtainAccessToken(this.loginData);
}
}
3.3. ホームコンポーネント
次に、ホームページの表示と操作を担当する HomeComponent を作成します。
@Component({
selector: 'home-header',
providers:[AppService],
template: `<span>Welcome !!</span>
<a (click)="logout()" href="#">Logout</a>
<foo-details></foo-details>`
})
export class HomeComponent {
constructor(
private __service:AppService){}
ngOnInit(){
this.__service.checkCredentials();
}
logout() {
this.__service.logout();
}
}
3.4. Fooコンポーネント
最後に、Fooの詳細を表示するための FooComponent :
@Component({
selector: 'foo-details',
providers:[AppService],
template: `<h1>Foo Details</h1>
<label>ID</label> <span>{{foo.id}}</span>
<label>Name</label> <span>{{foo.name}}</span>
<button (click)="getFoo()" type="submit">New Foo</button>`
})
export class FooComponent {
public foo = new Foo(1,'sample foo');
private foosUrl = 'http://localhost:8082/spring-security-oauth-resource/foos/';
constructor(private __service:AppService) {}
getFoo(){
this.__service.getResource(this.foosUrl+this.foo.id)
.subscribe(
data => this.foo = data,
error => this.foo.name = 'Error');
}
}
3.5. アプリコンポーネント
ルートコンポーネントとして機能するシンプルな AppComponent :
@Component({
selector: 'app-root',
template: `<router-outlet></router-outlet>`
})
export class AppComponent {}
そして、 AppModule ** __すべてのコンポーネント、サービス、およびルートをラップします。
@NgModule({
declarations:[ AppComponent,
HomeComponent,
LoginComponent,
FooComponent
],
imports:[ BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot([ { path: '', component: HomeComponent },
{ path: 'login', component: LoginComponent }])
],
providers:[],
bootstrap:[AppComponent]})
export class AppModule { }
4暗黙のフロー
次に、「暗黙のフロー」モジュールに注目します。
4.1. アプリサービス
同様に、私達は私達のサービスから始めますが、今回は自分自身でアクセストークンを取得する代わりにライブラリhttps://github.com/manfredsteyer/angular-oauth2-oidc[angular-oauth2-oidc]を使用します。
@Injectable()
export class AppService {
constructor(
private __router: Router, private __http: Http, private oauthService: OAuthService){
this.oauthService.loginUrl = 'http://localhost:8081/spring-security-oauth-server/oauth/authorize';
this.oauthService.redirectUri = 'http://localhost:8086/';
this.oauthService.clientId = "sampleClientId";
this.oauthService.scope = "read write foo bar";
this.oauthService.setStorage(sessionStorage);
this.oauthService.tryLogin({});
}
obtainAccessToken(){
this.oauthService.initImplicitFlow();
}
getResource(resourceUrl) : Observable<Foo>{
var headers = new Headers({'Content-type': 'application/x-www-form-urlencoded; charset=utf-8', 'Authorization': 'Bearer '+this.oauthService.getAccessToken()});
var options = new RequestOptions({ headers: headers });
return this.__http.get(resourceUrl, options)
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
isLoggedIn(){
if (this.oauthService.getAccessToken() === null){
return false;
}
return true;
}
logout() {
this.oauthService.logOut();
location.reload();
}
}
4.2. ホームコンポーネント
私たちの HomeComponent は私たちの単純なホームページを処理します。
@Component({
selector: 'home-header',
providers:[AppService],
template: `
<button ** ngIf="!isLoggedIn" (click)="login()" type="submit">Login</button>
<div ** ngIf="isLoggedIn">
<span>Welcome !!</span>
<a (click)="logout()" href="#">Logout</a>
<br/>
<foo-details></foo-details>
</div>`
})
export class HomeComponent {
public isLoggedIn = false;
constructor(
private __service:AppService){}
ngOnInit(){
this.isLoggedIn = this.__service.isLoggedIn();
}
login() {
this.__service.obtainAccessToken();
}
logout() {
this.__service.logout();
}
}
4.3. Fooコンポーネント
私たちの FooComponent は、パスワードフローモジュールとまったく同じです。
4.4. アプリモジュール
最後に、私たちの AppModule :
@NgModule({
declarations:[ AppComponent,
HomeComponent,
FooComponent
],
imports:[ BrowserModule,
FormsModule,
HttpModule,
OAuthModule.forRoot(),
RouterModule.forRoot([ { path: '', component: HomeComponent }])
],
providers:[],
bootstrap:[AppComponent]})
export class AppModule { }
5フロントエンドを実行する
{空} 1フロントエンドモジュールを実行するには、まずアプリを構築する必要があります。
mvn clean install
{空} 2。それから、Angularアプリディレクトリに移動する必要があります。
cd src/main/resources
{空} 3。最後に、アプリを起動します。
npm start
サーバーはデフォルトでポート4200で起動し、任意のモジュールのポートを変更します。
"start": "ng serve"
たとえば package.json で、ポート8086で実行するには
"start": "ng serve --port 8086"
6. 結論
このクイックチュートリアルでは、Angular 4フロントエンドを使用してAngular JSアプリケーションをアップグレードする方法を説明しました。
いつものように、完全なソースコードはhttps://github.com/Baeldung/spring-security-oauth[over on GitHub]にあります。