@pantoia/auth-client 0.1.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @pantoia/auth-client
|
|
2
2
|
|
|
3
|
-
쿠키로 인증하는 API를 브라우저에서
|
|
3
|
+
쿠키로 인증하는 API를 브라우저에서 호출하는 클라이언트다.
|
|
4
4
|
|
|
5
5
|
- access 토큰이 만료되면 재발급하고 요청을 다시 보낸다.
|
|
6
6
|
- 내 정보를 1번 불러와 저장하고, 로그인 여부와 권한을 그 값으로 확인한다.
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
npm install @pantoia/auth-client
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
React 훅을 쓰려면 React 18 이상이 필요하다.
|
|
15
|
+
Node 20.11 이상에서 동작한다. React 훅을 쓰려면 React 18 이상이 필요하다.
|
|
16
16
|
|
|
17
17
|
## 만들기
|
|
18
18
|
|
|
@@ -33,17 +33,17 @@ export const auth = createAuthClient<Me>({
|
|
|
33
33
|
|
|
34
34
|
| 옵션 | 뜻 |
|
|
35
35
|
|---|---|
|
|
36
|
-
| `baseUrl` | API 주소. 함수면 요청할 때마다
|
|
36
|
+
| `baseUrl` | API 주소. 함수면 요청할 때마다 호출한다 |
|
|
37
37
|
| `endpoints` | 내 정보, 재발급, 로그아웃 경로 |
|
|
38
38
|
| `codes.unauthenticated` | access 토큰이 없거나 만료됐을 때 오는 401 응답의 `code` |
|
|
39
39
|
| `codes.refreshConflict` | 다른 요청이 먼저 재발급했을 때 오는 409 응답의 `code` |
|
|
40
40
|
| `permissionsOf` | 내 정보에서 권한 목록을 꺼내는 함수 |
|
|
41
|
-
| `loginUrl` | 로그인 화면 주소. 함수면 쓸 때마다
|
|
41
|
+
| `loginUrl` | 로그인 화면 주소. 함수면 쓸 때마다 호출한다 |
|
|
42
42
|
| `returnToParam` | 로그인 뒤 돌아올 주소를 담는 쿼리 이름. 기본값은 `return_to` |
|
|
43
|
-
| `onUnauthenticated` | 재발급이 401로 실패했을 때
|
|
43
|
+
| `onUnauthenticated` | 재발급이 401로 실패했을 때 호출하는 함수 |
|
|
44
44
|
| `conflictRetryDelayMs` | 409 뒤에 다시 보낸 요청이 또 401일 때 기다리는 시간. 기본값은 300 |
|
|
45
45
|
|
|
46
|
-
## API
|
|
46
|
+
## API 호출하기
|
|
47
47
|
|
|
48
48
|
```ts
|
|
49
49
|
const response = await auth.fetch("/v1/items", { method: "POST", body: { name: "a" } });
|
|
@@ -56,7 +56,7 @@ await auth.fetch("/v1/auth/login", { method: "POST", body: { email, password },
|
|
|
56
56
|
- `body`가 객체면 JSON으로 보내고, `FormData`, `Blob`, `URLSearchParams`, 문자열은 그대로 보낸다.
|
|
57
57
|
- 실패 응답은 `ApiError`로, 서버에 닿지 못하면 `NetworkError`로 던진다. `signal`로 중단하면 `AbortError`를 그대로 던진다.
|
|
58
58
|
- `ApiError`에는 `status`, `code`, `message`(응답의 `detail`), `errors`(필드 오류), `retryAfterSeconds`, `data`(응답의 `data`, 타입은 `unknown`)가 있다. `data`의 모양은 오류 코드마다 다르고, 쓰는 앱이 코드를 보고 확인해서 쓴다.
|
|
59
|
-
- 로그인이 필요 없는 API는 `auth: false`로
|
|
59
|
+
- 로그인이 필요 없는 API는 `auth: false`로 호출한다. 재발급을 기다리지 않고, 401이어도 재발급하지 않는다.
|
|
60
60
|
|
|
61
61
|
## 재발급
|
|
62
62
|
|
|
@@ -66,22 +66,22 @@ await auth.fetch("/v1/auth/login", { method: "POST", body: { email, password },
|
|
|
66
66
|
- 요청을 보낸 뒤 다른 요청이 재발급을 끝냈으면 재발급하지 않고 다시 보낸다.
|
|
67
67
|
- 재발급이 성공하면 원래 요청을 다시 보낸다.
|
|
68
68
|
- 재발급이 409이고 `code`가 `codes.refreshConflict`면 재발급을 다시 하지 않고 원래 요청을 다시 보낸다. 다시 보낸 요청이 또 401이면 `conflictRetryDelayMs` 뒤에 1번 더 보낸다.
|
|
69
|
-
- 재발급이 401이면 기다리던 요청을 모두 실패로 끝내고, 저장한 내 정보를 지우고, `onUnauthenticated`를 1번
|
|
69
|
+
- 재발급이 401이면 기다리던 요청을 모두 실패로 끝내고, 저장한 내 정보를 지우고, `onUnauthenticated`를 1번 호출한다.
|
|
70
70
|
- 재발급이 네트워크 오류로 실패하면 요청만 실패로 끝낸다.
|
|
71
71
|
|
|
72
72
|
## 내 정보와 권한
|
|
73
73
|
|
|
74
74
|
| 함수 | 하는 일 |
|
|
75
75
|
|---|---|
|
|
76
|
-
| `getMe()` | 저장한 내 정보를 돌려준다. 없으면 요청하고, 동시에
|
|
77
|
-
| `reloadMe()` | 내 정보를 다시 요청한다. 내 정보를 바꾼 뒤에
|
|
76
|
+
| `getMe()` | 저장한 내 정보를 돌려준다. 없으면 요청하고, 동시에 호출해도 요청은 1번이다. 로그인하지 않았으면 `null` |
|
|
77
|
+
| `reloadMe()` | 내 정보를 다시 요청한다. 내 정보를 바꾼 뒤에 호출한다 |
|
|
78
78
|
| `isLoggedIn()` | 저장한 내 정보가 있는지 돌려준다 |
|
|
79
79
|
| `hasPermission(p)`, `hasAnyPermission(ps)`, `hasAllPermissions(ps)` | 저장한 내 정보로 권한을 확인한다. 불러오기 전에는 `false` |
|
|
80
80
|
| `refresh()` | 재발급한다 |
|
|
81
|
-
| `logout()` | 로그아웃 API를
|
|
81
|
+
| `logout()` | 로그아웃 API를 호출하고 저장한 내 정보를 지운다 |
|
|
82
82
|
| `loginUrl(returnTo)` | 로그인 화면 주소에 돌아올 주소를 붙인다. 주지 않으면 현재 주소를 붙인다 |
|
|
83
83
|
|
|
84
|
-
`getMe()`는 `onUnauthenticated`를
|
|
84
|
+
`getMe()`는 `onUnauthenticated`를 호출하지 않는다. 로그인하지 않은 사람의 이동 주소는 호출한 쪽이 정한다.
|
|
85
85
|
|
|
86
86
|
다른 탭에는 알리지 않는다. 다른 탭에서 로그아웃하면 이 탭은 다음 요청의 재발급이 실패할 때 알게 된다.
|
|
87
87
|
|
|
@@ -98,7 +98,7 @@ function Header() {
|
|
|
98
98
|
```
|
|
99
99
|
|
|
100
100
|
- `useMe(auth)`는 저장한 내 정보를 돌려준다. 아직 불러오지 않았으면 `undefined`를 돌려주고 불러온다. 로그인하지 않았으면 `null`이다.
|
|
101
|
-
-
|
|
101
|
+
- 훅 2개 모두 `reloadMe()`, `logout()`, 재발급 실패 뒤에 다시 그린다.
|
|
102
102
|
|
|
103
103
|
## 로그인 확인 예
|
|
104
104
|
|
|
@@ -136,7 +136,7 @@ isAllowedReturnTo(value, rule)
|
|
|
136
136
|
|
|
137
137
|
## 개발
|
|
138
138
|
|
|
139
|
-
Node
|
|
139
|
+
개발 런타임은 Node 24 LTS다.
|
|
140
140
|
|
|
141
141
|
```
|
|
142
142
|
npm install 처음 한 번
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pantoia/auth-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "쿠키 인증 API 클라이언트. 토큰 재발급, 내 정보, 권한 확인, 로그아웃",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@testing-library/dom": "^10.4.2",
|
|
49
49
|
"@testing-library/react": "^16.3.3",
|
|
50
|
-
"@types/react": "^19.
|
|
51
|
-
"happy-dom": "^
|
|
52
|
-
"oxlint": "^1.
|
|
53
|
-
"react": "^19.
|
|
54
|
-
"react-dom": "^19.
|
|
50
|
+
"@types/react": "^19.3.0",
|
|
51
|
+
"happy-dom": "^21.0.4",
|
|
52
|
+
"oxlint": "^1.92.0",
|
|
53
|
+
"react": "^19.3.1",
|
|
54
|
+
"react-dom": "^19.3.1",
|
|
55
55
|
"typescript": "^7.0.2",
|
|
56
|
-
"vitest": "^
|
|
56
|
+
"vitest": "^5.1.0"
|
|
57
57
|
}
|
|
58
58
|
}
|