-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: 認証機構導入、いくつかでもページ作成 #115
Changes from 45 commits
8925ada
b1afd71
d0f0057
e6739c1
5ac3a8f
0f06454
e80a717
099313c
ea72f14
209ddb7
0ba05dd
f4c3551
dd0c033
851fc3b
ba2b075
fbc1557
ad5faf9
73a4294
c630f26
d72c8c0
79acefb
199fda7
2d9052c
8e7c20c
5e364f6
19dd9cf
5d9786a
2966900
bc4436a
05c707a
087bfc9
a140ab9
7109321
1340c4d
d98a190
1a7017e
5a574ae
fc43fc4
253fefa
7eab592
8e70d3f
f780a58
ab3426c
752b81d
f7c0648
47b6596
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ pnpm run dev | |
- web: [http://localhost:3000](http://localhost:3000) | ||
- api: [http://localhost:8080](http://localhost:8080) | ||
- minio ui: [http://localhost:9001](http://localhost:9001) | ||
- Firebase Auth Suite Auth:[http://localhost:4000/auth](http://localhost:4000/auth) | ||
|
||
### チェックアウト後 | ||
|
||
|
@@ -53,12 +54,49 @@ pnpm exec prisma studio | |
docker-compose exec mysql bash -c "mysql -u root -proot" | ||
``` | ||
|
||
### Authentication | ||
|
||
プロダクションのアイデンティティ管理には [Google Cloud Identity Platform (GCIP)](https://cloud.google.com/identity-platform) を使用します。 | ||
ただし、開発中はデフォルトで Firebase emulator を使う用になっています。 | ||
|
||
#### Firebase エミュレータを使用 | ||
|
||
特に設定は要りません。以下のユーザ名とパスワードのセットがデフォルトで入った状態で起動します。 noicon1 はアイコンが設定されていないユーザです。 | ||
認証方法はメール以外は使用できません。 | ||
|
||
``` | ||
[email protected] | ||
testuserexample1 | ||
[email protected] | ||
testuserexample2 | ||
[email protected] | ||
noicon1 | ||
``` | ||
|
||
#### GCIP につなぐ | ||
|
||
ローカル環境を GCIP 環境に接続することも可能です。以下のように環境変数をセットします。 | ||
|
||
``` | ||
# .env | ||
GOOGLE_APPLICATION_CREDENTIALS=/path/to/dir/gcloud-violet-credential.json | ||
GCLOUD_PROJECT=your-proj | ||
FIREBASE_AUTH_EMULATOR_HOST= | ||
``` | ||
|
||
``` | ||
# pkg/web/.env.local | ||
NEXT_PUBLIC_GCIP_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | ||
NEXT_PUBLIC_GCIP_AUTH_DOMAIN=your-proj.firebaseapp.com | ||
NEXT_PUBLIC_AUTH_EMULATOR= | ||
``` | ||
|
||
### Lambda 内のソースコードに変更があった際 | ||
|
||
Lambda Docker は起動時のコードが使用され続けるので、リビルドしても、再起動が必要です。これは一瞬で終わります。 | ||
Lambda Docker は、依存のバージョンアップをしたなど、場合によっては再起動が必要です。これは一瞬で終わります。 | ||
|
||
- `docker rm -f lambda; docker up -d lambda` | ||
- `docker up lambda` でアタッチされている状態のまま `CTRL-C` (`CTRL-\` で抜けれます)、その後 `docker up lambda` | ||
- `docker-compose rm -f lambda; docker-compose up -d lambda` | ||
- `docker-compose up lambda` でアタッチされている状態のまま `CTRL-C` (`CTRL-\` で抜けれます)、その後 `docker-compose up lambda` | ||
|
||
|
||
## コーディングルール | ||
|
@@ -68,6 +106,11 @@ Lambda Docker は起動時のコードが使用され続けるので、リビル | |
- `pnpm run lint -w` でチェック | ||
- `pnpm run lint:fix -w` で自動修正 | ||
|
||
### ルーティング | ||
|
||
- api, web ともに `/dev/` 配下は staging 以降はロードバランサで弾きます。 (予定) | ||
- 危険な操作ができるような API は作成を避けてください | ||
|
||
### Dockerfile | ||
|
||
- `hadolint` を使用します。ルール指定をスクリプト経由でしているので、スクリプトから起動してください | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
## googleapis/google-auth-library-nodejs awsclient.ts | ||
|
||
https://github.com/googleapis/google-auth-library-nodejs/blob/5ed910513451c82e2551777a3e2212964799ef8e/src/auth/awsclient.ts | ||
|
||
// Copyright 2021 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,17 @@ services: | |
- mysql_data:/var/lib/mysql | ||
- ./docker/dev/mysql/my.cnf:/etc/mysql/conf.d/my.cnf | ||
|
||
firebase: | ||
build: ./docker/dev/firebase | ||
restart: always | ||
ports: | ||
- 9099:9099 # Auth | ||
- 4000:4000 # Emulator Suite UI | ||
env_file: | ||
- ./.env | ||
working_dir: /opt/workspace | ||
command: firebase emulators:start --only=auth --project=emulator --import=seeder | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 起動コマンドが以前と少し違います。ログインは必要ありません。トンネルでも使えると思います There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 詳細理解できてないけど、私がセットアップしたときにはオフライン対応わからなくて諦めたんだよなー |
||
|
||
minio: | ||
image: minio/minio | ||
restart: always | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
FROM node:14-buster | ||
|
||
RUN apt-get update -y | ||
RUN ( \ | ||
apt-get install -y --no-install-recommends \ | ||
curl \ | ||
openjdk-11-jre-headless \ | ||
) | ||
RUN npm install -g firebase-tools | ||
COPY . /opt/workspace/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"emulators": { | ||
"auth": { | ||
"host": "0.0.0.0", | ||
"port": 9099 | ||
}, | ||
"ui": { | ||
"enabled": true, | ||
"host": "0.0.0.0", | ||
"port": 4000 | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
{ | ||
"kind": "identitytoolkit#DownloadAccountResponse", | ||
"users": [ | ||
{ | ||
"localId": "DPSkoJjj8KsGHcQbxTgrjBvWBvry", | ||
"createdAt": "1637156432583", | ||
"lastLoginAt": "1637156432583", | ||
"displayName": "Test User1", | ||
"photoUrl": "https://github.com/icons8/flat-color-icons/raw/master/svg/businessman.svg", | ||
"emailVerified": false, | ||
"email": "[email protected]", | ||
"salt": "fakeSaltgovA2leAJckPXg5eYKxn", | ||
"passwordHash": "fakeHash:salt=fakeSaltgovA2leAJckPXg5eYKxn:password=testuserexample1", | ||
"passwordUpdatedAt": 1637156432583, | ||
"validSince": "1637156432", | ||
"providerUserInfo": [ | ||
{ | ||
"providerId": "password", | ||
"email": "[email protected]", | ||
"federatedId": "[email protected]", | ||
"rawId": "[email protected]", | ||
"displayName": "Test User1", | ||
"photoUrl": "https://github.com/icons8/flat-color-icons/raw/master/svg/businessman.svg" | ||
} | ||
] | ||
}, | ||
{ | ||
"localId": "K9oXOw5p4rYejYmqSUnmOTszIayh", | ||
"createdAt": "1637156463904", | ||
"lastLoginAt": "1637156463903", | ||
"displayName": "No Icon1", | ||
"photoUrl": "", | ||
"emailVerified": false, | ||
"email": "[email protected]", | ||
"salt": "fakeSaltTtKyT0aMQ0ejTo3WMwE2", | ||
"passwordHash": "fakeHash:salt=fakeSaltTtKyT0aMQ0ejTo3WMwE2:password=noicon1", | ||
"passwordUpdatedAt": 1637156463903, | ||
"validSince": "1637156463", | ||
"providerUserInfo": [ | ||
{ | ||
"providerId": "password", | ||
"email": "[email protected]", | ||
"federatedId": "[email protected]", | ||
"rawId": "[email protected]", | ||
"displayName": "No Icon1", | ||
"photoUrl": "" | ||
} | ||
] | ||
}, | ||
{ | ||
"localId": "t5lq8rDTp238rIIhJm1se9xniNmR", | ||
"createdAt": "1637156455279", | ||
"lastLoginAt": "1637156455279", | ||
"displayName": "Test User2", | ||
"photoUrl": "https://github.com/icons8/flat-color-icons/raw/master/svg/businesswoman.svg", | ||
"emailVerified": false, | ||
"email": "[email protected]", | ||
"salt": "fakeSaltdbUljyCSmcidArL2dqed", | ||
"passwordHash": "fakeHash:salt=fakeSaltdbUljyCSmcidArL2dqed:password=testuserexample2", | ||
"passwordUpdatedAt": 1637156455279, | ||
"validSince": "1637156455", | ||
"providerUserInfo": [ | ||
{ | ||
"providerId": "password", | ||
"email": "[email protected]", | ||
"federatedId": "[email protected]", | ||
"rawId": "[email protected]", | ||
"displayName": "Test User2", | ||
"photoUrl": "https://github.com/icons8/flat-color-icons/raw/master/svg/businesswoman.svg" | ||
} | ||
] | ||
} | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{ "signIn": { "allowDuplicateEmails": false } } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"version": "9.22.0", | ||
"auth": { | ||
"version": "9.22.0", | ||
"path": "auth_export" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { defineController } from './$relay' | ||
|
||
export default defineController(() => ({})) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export type Methods = Record<string, never> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { getCachedApp } from '@violet/api/src/service/firebase-admin' | ||
import { defineController } from './$relay' | ||
|
||
// https://firebase.google.com/docs/auth/admin/manage-cookies | ||
export default defineController(() => ({ | ||
post: async ({ body: { idToken }, env, logger, setCookie }) => { | ||
// TODO(security): kick too old tokens | ||
const auth = getCachedApp({ env, logger }).auth() | ||
// 5 days | ||
const expiresIn = 60 * 60 * 24 * 5 * 1000 | ||
const sessionCookie = await auth.createSessionCookie(idToken, { expiresIn }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 日数は要相談ですが、5 days でもワンクリックでログインできるのでそんなに大変でもないです There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 長期のセッション保存を大手に任せて、自分側では短くするというのは方針としては正しいと思っている There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 個人的にはサイトを開いている間自動でリフレッシュしてくれればトークンは短命でもいい |
||
setCookie('session', sessionCookie, { | ||
signed: true, | ||
maxAge: expiresIn, | ||
httpOnly: true, | ||
secure: process.env.NODE_ENV === 'production', | ||
path: '/', | ||
}) | ||
return { | ||
status: 200, | ||
body: {}, | ||
} | ||
}, | ||
delete: async ({ setCookie }) => { | ||
setCookie('session', '', { | ||
maxAge: 0, | ||
path: '/', | ||
}) | ||
return { | ||
status: 200, | ||
body: {}, | ||
} | ||
}, | ||
})) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export type Methods = { | ||
post: { | ||
reqBody: { | ||
idToken: string | ||
} | ||
} | ||
delete: { | ||
reqBody: Record<string, never> | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { defineController } from './$relay' | ||
|
||
export default defineController(() => ({ | ||
get: async ({ getUserClaims }) => ({ | ||
status: 200, | ||
body: await getUserClaims(), | ||
}), | ||
})) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awsclient.ts をコピペして改造したのでライセンス明記しています