Merged PR 137: アクセストークン内に階層情報を含める

## 概要
[Task1925: アクセストークン内に階層情報を含める](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/1925)

- アクセストークンとリフレッシュトークンにtierを追加

## レビューポイント
- tierのチェックは必要か
- DBの値をそのまま入れているが問題ないか

**以下は別タスクとして切り出す**
- RoleGuardsを拡張してtierもチェックできるようにする処理を追加し、階層ごとに許可される操作をI/Fの属性として宣言的にチェックできるように修正した箇所について、使いやすそうか。
例)
@UseGuards(RoleGuard.requireds({ roles: ['admin', 'author'] }))
の場合(階層の宣言はしていない場合)許可@UseGuards(RoleGuard.requireds({ roles: ['admin', 'author'], tier [2] }))の場合(階層の宣言をしている場合)ユーザのアカウントの階層を見て、2以上なら許可、2未満なら拒否
 

## UIの変更
- なし

## 動作確認状況
- ローカルで確認

## 補足
- https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/OMDSDictation/_wiki/wikis/OMDSDictation_wiki/202/%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3
wikiにアクセストークンとリフレッシュトークンについてのページを記載しました。
This commit is contained in:
maruyama.t 2023-06-08 08:28:10 +00:00
parent 3dca5c604b
commit c4aaee07b1
5 changed files with 29 additions and 1 deletions

View File

@ -1,8 +1,8 @@
// トークンの型やtypeGuardの関数を配置するファイル
// TODO トークンの型は仮
export interface Token {
userId: string;
role: string;
tier: number;
exp: number;
iat: number;
}
@ -16,6 +16,9 @@ export const isToken = (arg: any): arg is Token => {
if (arg.role === undefined) {
return false;
}
if (arg.tier === undefined) {
return false;
}
if (arg.exp === undefined) {
return false;
}

View File

@ -28,6 +28,7 @@ export const ErrorCodes = [
'E010203', // 管理ユーザ権限エラー
'E010204', // ユーザ不在エラー
'E010205', // DBのRoleが想定外の値エラー
'E010206', // DBのTierが想定外の値エラー
'E010301', // メールアドレス登録済みエラー
'E010302', // authorId重複エラー
'E010401', // PONumber重複エラー

View File

@ -17,6 +17,7 @@ export const errors: Errors = {
E010203: 'Administrator Permissions Error.',
E010204: 'User not Found Error.',
E010205: 'Role from DB is unexpected value Error.',
E010206: 'Tier from DB is unexpected value Error.',
E010301: 'This email user already created Error',
E010302: 'This AuthorId already used Error',
E010401: 'This PoNumber already used Error',

View File

@ -7,6 +7,10 @@ export type RefreshToken = {
* Roleを表現する文字列(ex. "author admin")
*/
role: string;
/**
* 1~5
*/
tier: number;
};
export type AccessToken = {
@ -18,6 +22,10 @@ export type AccessToken = {
* Roleを表現する文字列(ex. "author admin")
*/
role: string;
/**
* 1~5
*/
tier: number;
};
export type IDToken = {

View File

@ -72,6 +72,19 @@ export class AuthService {
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
// Tierのチェック
const minTier = 1;
const maxTier = 5;
const userTier = user.account.tier;
if (userTier < minTier || userTier > maxTier) {
this.logger.error(
`Tier from DB is unexpected value. tier=${user.account.tier}`,
);
throw new HttpException(
makeErrorResponse('E010206'),
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
// 要求された環境用トークンの寿命を決定
const refreshTokenLifetime = type === 'web' ? lifetimeWeb : lifetimeDefault;
@ -105,6 +118,7 @@ export class AuthService {
? ADMIN_ROLES.ADMIN
: ADMIN_ROLES.STANDARD
}`,
tier: user.account.tier,
userId: idToken.sub,
},
refreshTokenLifetime,
@ -132,6 +146,7 @@ export class AuthService {
const accessToken = sign<AccessToken>(
{
role: token.role,
tier: token.tier,
userId: token.userId,
},
lifetime,