はまったりひらめいたり…とか…

.Net系プログラムで勉強したこととか嵌ったことについて書いたりします。

AngularとAzureAD認証でログイン機構を簡単に実現したい

最初に

今回使用した環境は下記の通りです。

  • @angular/cli : 6.0.8
  • @angular : 6.0.7

AzureAD認証を支援するJSライブラリ

AzureActiveDirectory認証を支援するJSライブラリとして

MicrosoftからADALというJSライブラリが提供されています。

github.com

マルチテナント型のAzureADB2CはMSALと呼ばれるライブラリを使用するようです。

github.com

ADALのAngularラッパーを取得

Angular使いなので、Angularでadal.jsを使おうと思います。

adal.js自体はnpmでパッケージ提供されていないようです。。。

Angularで使用できるラッパーは提供されているようなのでそいつを使用していきます。

npm install adal-angular4 --save

Angular4と書かれていますが6も対応されています。

Angular6対応版もありますが、Deprecateして4に吸収されているようです。

github.com

(名前、ngx~みたいな形のほうがわかりやすいですよね…)

ServiceをImportしてProvide

まずはInjection宣言されている、AdalSeviceを app.module.ts でProvideします。

import { AdalService } from 'adal-angular4';

・・・

providers: [
    AdalService
],

ADの情報を設定

AdalService.init() に使用するADの情報を食わせる必要があります。

Sampleで指定されているのではTenantとClientIDです。

TenantはADで使用されているドメイン

ClientIDはADに登録されたアプリケーションのApplicationIDを指定します。

handleWindowCallbackでログイン状態の収集

先程ProvideしたAdalServiceを介して認証情報のやり取りを行います。

サービス内の handleWindowCallback() を使用し

サインインされているか~ですとか、Tokenの情報~ですとか

そういった情報が収集されているようです。

ログインされているかの情報は

this._adalService.userInfo.authenticated で確認できるので

ログインされているかを確認し

ログインされていないようであればログインするようにしてみます。

  constructor(
    private _adalService: AdalService,
  ) { }

・・・

ngOnInit() {
    this._adalService.handleWindowCallback();
    if (!this._adalService.userInfo.authenticated) {
        this._adalService.login();
    }
}

このようにしておくと、Componentの初期化と同時に

AD未ログイン状態だった場合は

AzureActiveDirectoryの認証画面にリダイレクトされます。

AdalGuardでComponentの遷移Guard

AdalGuardは、Angularの CanActivate

上記の userInfo.authenticated を使用して

AD未ログインユーザーのRoutingの制限を行うSampleという認識です。

adal-angular4/adal.guard.ts at master · benbaran/adal-angular4 · GitHub

認証されていないユーザーへの移動制限をかけたい場合は

routerの設定のときにAdalGuardを指定するだけでOKといった塩梅です。

ここで認証されていない場合は強制的にリダイレクトかけたりなんだりしたいと思うので

基本的にAdalGuardをそのまま使用することはないかなぁ?と思っています。

今回はLoginComponentからDashboardComponentへの遷移の設定を作ってみます。

const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'dashboard', component: DashBoardComponent, canActivate: [AdalGuard] },
  { path: '', component: LoginComponent },
];

今回はAdalGuardをそのまま使用します。

認証がすでに済んでいるものはURL指定で直接遷移できていますが

認証が済んでいないほうはRouterで遷移ができずに

何も表示されていない状態になっています。

f:id:TakasDev:20180630122308g:plain

AD認証のAuthがかかったASP.net WebAPIへのアクセス

adal-angular4が提供する AdalInterceptor

AngularのHTTP_INTERCEPTORを使用して、ヘッダに認証情報を付与します。

adal-angular4/adal.interceptor.ts at master · benbaran/adal-angular4 · GitHub

なので、app.module.ts でInterceptorのInjectionを行えばいい感じです。

providers: [
    AdalService,
    {
        provide: HTTP_INTERCEPTORS,
        useClass: AdalInterceptor,
        multi: true
    }
],

WebAPIを作る

WebAPIはASP.net CoreでAD認証付きのAPIがテンプレートから作れるので

それでサクッと作ってしまいます。

f:id:TakasDev:20180630122458j:plain

F5実行して動作を見てみます。

アクセスするAPIはデフォルトで存在する /api/values のGetにアクセスしてみます。

まずは、RestletClientから、Token情報を付与しない状態でアクセスしてみます。

f:id:TakasDev:20180630122651p:plain

401エラーが返却されました。認証は問題なく動作しているようです。

AdalInterceptorを通してからアクセスした場合を見てみます。

f:id:TakasDev:20180630122744j:plain

横着してConsole出力で済ませています。

f:id:TakasDev:20180630123336p:plain

Networkからも、HeaderのAuthorizationにTokenが使用されているのが確認できます。

先程失敗したRestletClientで、使用されたTokenを使ってみます。

f:id:TakasDev:20180630123527p:plain

通りました。正しいTokenのようです。

まとめ

JSでのActiveDirectory認証はADALを使用します。

今回はAngularを使用しましたがVue用等

各Frameworkのものも用意されているようです。

ログイン画面やアカウント管理は非常に重要で気も使う部分です。

簡易な要望でADを使用している人や会社が対象であれば

AD認証で認証ロジックを丸投げしてしまうのもありですよね。

Desktop PWAs 体験してみた

最近話題になったこと

最近、WindowsのDesktopでPWAが動くぜー!と話題になっていました。

https://blogs.windows.com/msedgedev/2018/02/06/welcoming-progressive-web-apps-edge-windows-10/#o1UfZRcqAE1SGUem.97

英語力が低いので誤解しているかもしれないですが

これはストアアプリの内部としてPWAも使えるようになりますよー

ってアナウンスなのかなとも思っていました。

普通に動かす分にはもう出来るっぽい

medium.com

ちょっと調べてみると

上記の記事の内容からすると、もうPWAのWebAppを

アプリケーションとしてデスクトップに配置することは可能になっているようです。

というわけで試してみました。

かなり簡単に試すことができました。

Chromeの設定

ChromeのVersionは 64.0.3282.186(Official Build) (64 ビット) で試しました。

まずは chrome://flags/ で現在試験運用中のPWAs Desktopを使えるようにします。

f:id:TakasDev:20180224131744p:plain

Chromeの再起動が要求されるのでChromeの再起動を行います。

PWAのサイトを開く

PWA対応のサイトは下記のPWA Rocksから探せますので、お好きなサイトを立ち上げます。

pwa.rocks

今回は、MobileTwitterを使ってみます

https://mobile.twitter.com/home

デスクトップに追加する

メニューからデスクトップに追加できるようになっているのでデスクトップに追加します。

f:id:TakasDev:20180224132152p:plain

デスクトップにChromeアイコンではなく、アプリケーションのアイコンっぽいものが生えてきました!

恥ずかしいタイポは気にしないでください!

f:id:TakasDev:20180224132450p:plain

開いてみると、Chromeのブラウザではなく

アプリのウィンドウっぽい画面でTwitterが立ち上がりました!

f:id:TakasDev:20180224132402p:plain

最後に

PWAサイトをアプリケーションのように使うという

モバイルで出来ていたことがWindowsでも実現できるようになりました。

PWAアプリケーションのすそ野がまた一つ広がりましたね!

お手軽に試せるので、皆様もぜひ試してみてください!

Reactive FormsでオリジナルのComponentを使用する

初めに

今回の記事は、下記構成でお送りします。

  • Angular: 5.1.1
  • AngularCli: 1.6.1

Reactive FormsでOriginalのComponentを使いたい

業務系のWebApp作るお仕事してるとReactive Formsを多用します。

Validatorのエラーチェック部分を楽に作れるのが気に入ってます。

ただ、DBから引っ張ってきたマスタListのSelectBoxとか

多くのところで使用するようなコントロールは共通化したいところです。

そこで、Component部品をReactive Formsで使用できないか試してみました。

まずは単純なReactive Forms

ログイン画面っぽいもの想定して、単純なReactive Formsの画面を作ってみます。

<form [formGroup]="inputForm">
  <input [formControlName]="USER_ID_KEYWORD" placeholder="ユーザーID" />
  <label style="color:red" *ngIf="formErrors[USER_ID_KEYWORD]">{{formErrors[USER_ID_KEYWORD]}}</label>
  <br/>
  <input [formControlName]="PASSWORD_KEYWORD" placeholder="パスワード" />
  <label style="color:red" *ngIf="formErrors[PASSWORD_KEYWORD]">{{formErrors[PASSWORD_KEYWORD]}}</label>
</form>

ユーザーIDコントロールだけ切り出し、別Componentに

  • ユーザーIDコントロールapp-user-id-textという名前で作成しました
<form [formGroup]="inputForm">
  <app-user-id-text [formControlName]="USER_ID_KEYWORD"></app-user-id-text>
  <label style="color:red" *ngIf="formErrors[USER_ID_KEYWORD]">{{formErrors[USER_ID_KEYWORD]}}</label>
  <br/>
  <input [formControlName]="PASSWORD_KEYWORD" placeholder="パスワード" />
  <label style="color:red" *ngIf="formErrors[PASSWORD_KEYWORD]">{{formErrors[PASSWORD_KEYWORD]}}</label>
</form>

まずは、単純に、新しく作成したComponentに

ユーザーIDで使用してたFormControlNameを使用してみます。

エラー

f:id:TakasDev:20171221220818j:plain

ですよねー。ってことで修正します。

Reactive Formsの作り方を思い出す

Reactive Formsは、ComponentのInit時に、下記のように作成したはずです。

buildForm() {
    this.inputForm = this.fb.group(this.formSetting);
    this.inputForm.valueChanges.subscribe(data => {
        this.onValueChange(data);
    });
    this.onValueChange();
}

FormのSetting情報を、FormBuilder.groupを使用して

FormGroupプロパティに突っ込んでいます。

つまり、Componentに対してFormGroupの情報を送ってやれば良いのかもしれません。

子ComponentにFormGroupのプロパティを生やす

@Input() fg: FormGroupのプロパティを生やしました。

export class UserIdTextComponent implements OnInit {

  @Input()
  fg: FormGroup;

...
}

Componentを使用する際に

<app-user-id-text [fg]="hogeForm"> ... みたいな感じで使用します。

結果

f:id:TakasDev:20171221221321g:plain

通りました。

入力内容が@InputのFormGroupを通して、親Componentに伝播し

また、オリジナルComponentのValidationエラーが

親Componentのエラーメッセージプロパティに格納されました。

最後に

今回作成したコードは、下記にあげてあります。

煮るなり焼くなりお好きにしてくださいませ。

github.com

…Angular v2時代に作った勉強用のリポジトリそろそろ名前変えないとなぁ…

Xamarin.AndroidでNfc機能の技術検証した話

この記事は

[初心者さん・学生さん大歓迎!] Xamarin その1 Advent Calendar 2017

13日目の記事となります。Advent Calendar初挑戦です。よろしくお願いします!

初めに

Xamarin.Formsはずいぶん前からちょこちょこ触ってましたが

本業はWebの方のお仕事中心で、正直まだまだ初心者の域を脱していません。

ですが、最近、Nativeの技術検証をする機会がありましたので

Xamarinで色々やってみた話です。

Xamarin.Androidの話になります。iOSまでは手を出せませんでした。

今回の記事はコードなしで感想中心となります。

コードは後述するGitHubに上げてますので煮るなり焼くなり致してくださいませ。

技術検証したこと

AndroidNfcを使用し、Suicaとかから履歴情報を引き抜く

まずはkotlin

AndroidにおけるSuicaから履歴を抜く方法については検索してすぐ見つかりました。

特に参考になったのは下記のページです。

qiita.com

qiita.com

www.kotemaru.org

が、JavaやKotlinのコードをC#に素直に変換できるか不安がありました。

なので、まずはkotlinで実装し

どのように動作するのか確認しながらC#に落とし込む手法を取りました。

基本は上記のページを参考に、kotlinの実装と動作を確認しつつ写経しました。

GitHub - Takas0522/FelicaCardReaderSample: FelicaCardReaderをKotlinで作ってみたSample

kotlinで出来上がったのが上記のコードです。

NFCAPIを使用し、Byte配列のコマンドを投げ

リクエストをByte配列で受け取る方式で、カードの履歴情報を取得します。

Xamarin.Android

はまったか?

案外、ハマる部分は少なく、素直に移行できたかと思います。

と、いうのも、NFCのやりとりで使用するNfcFクラスといったクラスの使い方は

ほぼ、kotlinのときと同様の使い方ができたので

その部分については迷うことは少なかったです。

(「Byte配列作る→投げる→Byte配列もらう」だけなので特例とは思いますが…)

なので、Xamarin特有(?)のR→Resourceとか、Intent周り等

基本的な、且つ、kotlinやJavaの記法から変わってる部分で少しハマったりしました。

最終的に、そういった基本的な部分で困ったら

Xamarin公式のドキュメントからサンプルソース落として

基本動作を抑える解決方法に落ち着きました。

kotlinで先に書いてみた恩恵

今回は特殊なケースかもしれませんが

Xamarinでうまく動作できないとき、kotlinで動作させてみて

Byte配列の変数の状態等をチェックすることもできたので

先にkotlinでコード書いてみたのが非常に活かせることができました。

Xamarinでうまく動かないときは

同様な動作をkotlin等のNativeコードで動かしてみると

色々気づきがあるかもしれません。

kotlinの書き換えが地味に多い

kotlinはオブジェクト操作周りが充実している印象で

その周りのC#の書き換えが地味に多かったです。

(Byte配列いじくることばっかやってたのでだいぶ偏った印象かも。。)

.netから見たkotlinの良さは、@amay077 さんの記事が参考になるかと思います。

qiita.com

自分は、Byte配列のここからここまでコピーする。みたいな CopyOfRange とか

Byte配列の Write ファンクションでByte配列に値を格納していくー。みたいな

Kotlin標準の機能の拡張を我慢できずに作ったりはしました。

ほかの言語に触れることでよさげな機能を発見して

C#の実装に取り込むといったことができるのも

Nativeコードに触れる良さかな。と思いました。

まとめ

  • 勉強目的ならNativeコードから書いたほうが格段に良い

    • 使用するNativeAPIの使い方が理解しておくことで、C#への移行がスムーズに。
    • kotlinで動作するものを作ることで、C#で動作しないときの比較検証ができた。
    • JXUGの勉強会ではよく耳にしますが本当に実感できました…!!
  • NativeコードからのC#への移行はあんがいあっさり行えた

    • ただし、NativeAPIをほとんど使用していない。
    • NativeAPIを多用し始めるとまた別の落とし穴が見えてくるはず
  • 基本的な部分はXamarin公式ドキュメントのサンプルで粗方洗える

    • iOSのCoreNFCとか新し目のAPIのサンプルもあったりするので結構ニッチな部分も抑えれるかも…

さいごに

今回作成したXamarin.Androidのコードは下記になります。

GitHub - Takas0522/FelicaCardReaderSampleXamarin

明日のAdventCalendarは @masanori-_-msl さんです。

よろしくお願いします!

AzureのVMと自社サーバーをVPNでつなげて(かんたんな)Deployをしてみる

実験的要素モリモリでございます。

ビルドサーバーのVirtualMachineはAzure上にある。

でも、検証環境は自社の閉域ネットワーク内のどこそこにある。といった場合に。

(きわめてレアだとは思いますが!)

ちなみに使用するGatewayとか高めのお値段なので

自前の閉域環境内にサーバ用意できるのであればそちらのほうが良いと思います。

どちらかというとIaaSの環境をVPNで自社VPNに接続する手法がメインとなりますし

そちら単独のほうがよくあるパターンだとは思います。

CIは「いけんじゃね?」的なフィーリングの実験です。

下図な感じの構成で今回作ってみます。

f:id:TakasDev:20171104111618p:plain

参考資料

Point To Site

docs.microsoft.com

docs.microsoft.com

docs.microsoft.com

VSTSとJenkinsをつなげるときに参考

docs.microsoft.com

blog.nextscape.net

Jenkins

Windows Serverへのインストール

Azure準備

まずはAzure上の環境を構築します。

Azure上で作成したVM仮想環境から、閉域環境内(社内等)にVPN接続できる状態まで持っていきます

[Point To Site]という手法を使用します。

Point To Site構成の作成

仮想ネットワークのアドレス空間の追加

仮想ネットワークサブネットの作成

  • 上記で作成した仮想ネットワークアドレス空間を対象に設定します。
  • バックエンドのサブネットとゲートウェイサブネットを追加します。

    f:id:TakasDev:20171104103241p:plain

    f:id:TakasDev:20171104103310p:plain

仮想ネットワークゲートウェイの作成

  • 先ほど設定した仮想ネットワークをターゲットにゲートウェイを作成します。

    f:id:TakasDev:20171104103915p:plain

自己証明書を作成

  • WindowsServer2016以降の場合
    • PowerShellで[New-SelfSignedCertificate]実行が鉄板です。
  • MakeCer.exeを使用したい場合

  • できあがったルート証明書とクライアント証明書のCerとPfxをエクスポートします。

    • pfxはbase64形式でエクスポートします。

ゲートウェイの設定

  • アドレスプールとルート証明書を設定します。
  • アドレスプールはこれまで指定してきたものと別のIPアドレス空間を指定します
    • ([10.0.0.0/24]とか指定したら[10.1.0.0/24]みたいな感じですかね?)
  • 上記で作成した証明書をエディタかなにかで開き内部コードを編集します。
    • 改行コードが入っているので、改行部分をつぶします。

VirtualGatewayのセットアップ

  • 先程改行コードを潰したpfx内の文字列を設定します。
  • VPNクライアントをインストールします

接続設定の変更

※この作業が必要かどうかはちょっと微妙ですが

  • AzureVMクからライアント環境への参照はそのままでは行えないです。
  • インターネットオプション/Chromeの[設定]>[詳細詳細]>[プロキシ設定を開く]から[接続]の設定
  • 先ほど作成したVPNクライアントを選択し[設定]

f:id:TakasDev:20171104104608p:plain

  • 「設定を自動的に検出する」

接続の確認

作成したVPN内のIPアドレスは、コマンドプロンプトの[ipconfig]で確認することができます。

特に設定していないため、下図のIPアドレスVPNの接続の度変わります。

以降の図等でのIPアドレスの表記は、下図のものと異なる場合があります。

f:id:TakasDev:20171104104711p:plain

ネットワーク設定でリモート接続やファイル共有を

プライベートネットワーク内でできるようにしたうえで

AzureのVM上からVPN内の端末にアクセスできるか試してみます、

f:id:TakasDev:20171104104945p:plain

問題なく接続できるようです。

VSTSの設定

アカウント設定

Jenkinsからソースを抜けるように、VSTSの[authentication credentials]を設定します。

ユーザー名の[Security]>[authentication credentials]から設定可能です。

f:id:TakasDev:20171104105730p:plain

Jenkinsの設定

インストール

公式のドキュメントどおりにインストールします。

ビルド環境準備

  • Java SDK
    • Jenkins-CLI動かすのにJavaが必要なので
  • Git
    • Git管理用
    • [Use Git from the windows...]をチェックしといたほうが良いと思います。

以降必要があれば…

CI環境の設定

ひとまず今回はてっとりばやく、VSTSから取得したAngularをBuildした成果物を

VPN内の共有ディレクトリに突っ込む方法で検証してみます。

下記の感じでPowerShellスクリプトを実行します。

  1. npm i - Javascriptパッケージインストール
  2. ng build - JavascriptBuild
  3. Copy-Item - 成果物の移動

回してみる

AzureのVMから、Jenkinsを使ってVPN内のパスにDeployできるようになりました。

f:id:TakasDev:20171104112129g:plain

Azureハイブリッド接続でAzureWebAppsとオンプレミスのDBをつなげよう

AzureにWebAppsを置いてもいいけど他アプリケーションとの連携の関係で

SQLDatabaseはオンプレミスサーバーに置いときたい!なんて事が合った場合に。

ちと手順が複雑で日本語の最新資料も見当たらなかったのでメモ書き程度に。

参考文献

少し古いですが、AtoZ等は↓を

github.com

ハイブリッド接続に関しては↓を参考にしました。

docs.microsoft.com

準備

まずは、SQLServerを立てるオンプレミス環境とWebAppsを準備します。

自前の環境に直接つなげるのはあれなので

無償期間内で使用できるWindwosServerを使用しました。

www.microsoft.com

AzureのWebAppsは今回使用する「ハイブリッド接続」が

Basicからの対応となっているので、B1環境で構築しました。

(Basic環境はサポート対象外のようなので、実運用はStandardからですね!)

SQLServerの準備

SQLServerのExpress版をオンプレミスの仮想環境内に突っ込みます。

TCP通信できるようにしておきます。

詳細な手順については手順を説明しているサイトが多くあるのでそちらをご参考ください。

ServiceBusの構築

ハイブリッド接続で使用するAzure ServiceBusを構築します。

設定するものは名前ぐらいで、特別な設定等は行っていないので、詳細は省きます。

WebAppsでハイブリッド接続の設定

WebAppsの「ネットワーク」>「ハイブリッド接続」>「ハイブリッドエンドポイントの構成」から

ハイブリッド接続の設定画面に行くことが出来ます。

f:id:TakasDev:20171014230502p:plain

「ハイブリッド接続の追加」> 「ハイブリッド接続の新規作成」から

ハイブリッド接続設定を追加できます。

f:id:TakasDev:20171014230546p:plain

  • ハイブリッド接続の名前
    • 適当にそれっぽい名前をつけました。
  • エンドポイントホスト
    • エンドポイントのホスト名(オンプレミスサーバーの名)を付けました。
  • エンドポイントポート
    • SQLServerの標準のTCPポートの1433を使用しました。
  • サービスバス
    • 既存で先ほど作成したサービスバスを使用するようにしました。

オンプレミス環境からの接続

ハイブリッド接続設定画面の「接続マネージャダウンロード」で

クライアントソフトウェアをダウンロードします。

インストーラはオンプレミスDBが存在するサーバ上で実行します。

f:id:TakasDev:20171014230636p:plain

インストールしたソフトウェア「Hybrid Connection Manager UI」を起動すると

Azureにログインするためにログイン画面がたちあがあります。

先ほどハイブリッド接続の設定を行ったアカウントでログインします。

f:id:TakasDev:20171014230700p:plain

「Configure another Hybrid Connection」でハイブリッド接続の接続設定を行います

f:id:TakasDev:20171014230722p:plain

Subscripyionでハイブリッド接続の設定を作成したサブスクリプションを選択すると

サブスクリプションに紐づくハイブリッド接続の一覧が表示されます。

その中から使用する接続設定を選択し、[save]で決定します。

Connectedになったら接続設定完了です。

f:id:TakasDev:20171014230700p:plain

WebAppsとDBの接続確認

まずはローカル環境でDBに接続できるWebAppをサクッと作成します。

VS2017のテンプレートだと、ASP.netMVCのSPAテンプレートが

確認しやすいと思います。

web.configの接続文字列を書き換えるだけでOKなので。

f:id:TakasDev:20171014230819p:plain

f:id:TakasDev:20171014230851p:plain

ひとまず、Localでの実行で「devtakas@devtakas.com」でユーザーを作成してみました。

発行

いつもの手順でハイブリッド接続の設定を行ったWebAppsに発行を行います。

発行されたWebAppsに「「devtakas@devtakas.com」」でログインしてみます。

ログイン失敗!

ログインしようとするとエラーが発生してしまいました。

SQLServerの名前付インスタンスは動的ポートとしてUDPをしようするそうですが

これはハイブリッド接続ではサポートされないそうです。

なので、SQLServerの名前付きインスタンスの構成を変更します。

SQLServerのネットワーク構成の変更

SQLServer構成マネージャ」プログラムから

今回対応する名前付きインスタンスのネットワークプロトコル構成を選択します。

f:id:TakasDev:20171014230919p:plain

TCP/IPのプロパティで「IPアドレス」タブを選択し、参考資料に合った通り

IPAIIのTCPPortを、上記エンドポイントで指定した1433ポートを指定しました。

f:id:TakasDev:20171014230947p:plain

変更後、ホスト名のみでDB接続できるようになっていればOKです。

成功!

f:id:TakasDev:20171014231050p:plain

オンプレで登録したユーザー情報でログインできました!

Angular Materialを自分好みのカラーパレットに変更する

はじめに

下記バージョン構成でお送りします。

Angular : 4.4.4

Angular-cli : 1.4.3

Angular Material:2.0.0-beta.12

Angular Material

Angular Material

まだβなんですが、主たるコントロールはそろっているので

angularでマテリアルデザインのサイトを作りたいときは

非常に重宝するかと思います。

ただ、現在のテンプレートのカラーパレットって↓みたいな感じのものしかないんですね

f:id:TakasDev:20171008093056p:plain

自分は紫好きなんでいいんですが

ここも自分で自由に変更出来たらモックサイト作るときに便利なので

自分好みの色で、Angular Materialを構成してみましょう。

まずはテンプレートのカラーパレットのCSSをみてみる

まずはGitHubCSSがどのような構成で作成されているのかみてみます。

github.com

deeppurple-amberのSCSSをみてみます。

$mat-deep-purpleにカラーパレットの設定が記述されてそうです。

では、$mat-deeppurpleを見てみます。

material2/_palette.scss at master · angular/material2 · GitHub

ここにはテーマのすべての設定が記述されているようなので、一部抜粋します。

$mat-deep-purple: (
  50: #ede7f6,
  100: #d1c4e9,
  200: #b39ddb,
  300: #9575cd,
  400: #7e57c2,
  500: #673ab7,
  600: #5e35b1,
  700: #512da8,
  800: #4527a0,
  900: #311b92,
  A100: #b388ff,
  A200: #7c4dff,
  A400: #651fff,
  A700: #6200ea,
  contrast: (
    50: $black-87-opacity,
    100: $black-87-opacity,
    200: $black-87-opacity,
    300: white,
    400: white,
    500: $white-87-opacity,
    600: $white-87-opacity,
    700: $white-87-opacity,
    800: $white-87-opacity,
    900: $white-87-opacity,
    A100: $black-87-opacity,
    A200: white,
    A400: $white-87-opacity,
    A700: $white-87-opacity,
  )
);

色はこのように指定されているようです。

この構成は、Googleが提供している

マテリアルデザインのカラーパレットと同じ構成になっています。

(同じGoogle提供なんだから当然といえば当然ですよね)

Color - Style - Material Design

これと同じ構成で好きな色

または、上記のサイトのカラーパレットそのまま使って

SCSSを作ってあげれば

自分好みの色のテーマのマテリアルデザインのサイトが作れそうです。

カラーパレットを作る

しかし、色彩の専門家でもないですし、マテリアルデザインの色の勉強もしてないので

これを好きな色から自分で考えて組むのは骨が折れそうです。

なので、ジェネレータを使用して、カラーパレットを作成しちゃいます。

mcg.mbitson.com

適当にこんな感じの色にしてみました。

f:id:TakasDev:20171008095516p:plain

Angular MaterialのカラーパレットのSCSSの形でOutputできるので非常に楽です。

Angular Materialを組み込む

deep-purpleのSCSSと同じようにSCSSを作成してみます。

@import '~@angular/material/theming';
@include mat-core();

$mat-custom: (
    50 : #fef9e8,
    100 : #fcf0c6,
    200 : #fae7a1,
    300 : #f7dd7b,
    400 : #f6d55e,
    500 : #f4ce42,
    600 : #f3c93c,
    700 : #f1c233,
    800 : #efbc2b,
    900 : #ecb01d,
    A100 : #ffffff,
    A200 : #fffaee,
    A400 : #ffeabb,
    A700 : #ffe2a1,
    contrast: (
        50 : #000000,
        100 : #000000,
        200 : #000000,
        300 : #000000,
        400 : #000000,
        500 : #000000,
        600 : #000000,
        700 : #000000,
        800 : #000000,
        900 : #000000,
        A100 : #000000,
        A200 : #000000,
        A400 : #000000,
        A700 : #000000,
    )
);


$cust-app-primary: mat-palette($mat-custom);
$cust-app-accent:  mat-palette($mat-pink, A200, A100, A400);
$cust-app-warn:    mat-palette($mat-red);

$cust-app-theme: mat-light-theme($cust-app-primary, $cust-app-accent, $cust-app-warn);

@include angular-material-theme($cust-app-theme);

SCSSはangular-cli.jsonのStylesで読み込ませると、ビルド時にCSSにしてくれるので

angular-cli.jsonで上記のSCSSをStylesに食わせるだけでOKです。

結果

わかりやすそうなComponentだけピックアップして表示してみました。

f:id:TakasDev:20171008122542p:plain

Primaryボタンが一番わかりやすいですが

問題なくOriginalのカラーパレットが使用されているようです。