Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
k-taro56
left a comment
There was a problem hiding this comment.
ありがとう!! 😊😊😊😊😊
とってもたすかる!!
src/db/adapter-pg.ts
Outdated
| async linkAccount(account) { | ||
| const exists = await client.query( | ||
| `SELECT EXISTS ( | ||
| SELECT 1 | ||
| FROM accounts | ||
| WHERE "userId" = $1 AND provider = $2 AND "providerAccountId" = $3 | ||
| );`, | ||
| [account.userId, account.provider, account.providerAccountId], | ||
| ); | ||
|
|
||
| let sql: string; | ||
| if (exists.rows[0].exists) { | ||
| sql = ` | ||
| update accounts set | ||
| type = $3, | ||
| access_token = $5, | ||
| expires_at = $6, | ||
| refresh_token = $7, | ||
| id_token = $8, | ||
| scope = $9, | ||
| session_state = $10, | ||
| token_type = $11 | ||
| where "userId" = $1 AND provider = $2 AND "providerAccountId" = $4 | ||
| returning | ||
| id, | ||
| "userId", | ||
| provider, | ||
| type, | ||
| "providerAccountId", | ||
| access_token, | ||
| expires_at, | ||
| refresh_token, | ||
| id_token, | ||
| scope, | ||
| session_state, | ||
| token_type | ||
| `; | ||
| } else { | ||
| sql = ` | ||
| insert into accounts | ||
| ( | ||
| "userId", | ||
| provider, | ||
| type, | ||
| "providerAccountId", | ||
| access_token, | ||
| expires_at, | ||
| refresh_token, | ||
| id_token, | ||
| scope, | ||
| session_state, | ||
| token_type | ||
| ) | ||
| values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) | ||
| returning | ||
| id, | ||
| "userId", | ||
| provider, | ||
| type, | ||
| "providerAccountId", | ||
| access_token, | ||
| expires_at, | ||
| refresh_token, | ||
| id_token, | ||
| scope, | ||
| session_state, | ||
| token_type | ||
| `; | ||
| } | ||
|
|
||
| const params = [ | ||
| account.userId, | ||
| account.provider, | ||
| account.type, | ||
| account.providerAccountId, | ||
| account.access_token, | ||
| account.expires_at, | ||
| account.refresh_token, | ||
| account.id_token, | ||
| account.scope, | ||
| account.session_state, | ||
| account.token_type, | ||
| ]; | ||
|
|
||
| const result = await client.query(sql, params); | ||
| return mapExpiresAt(result.rows[0]); | ||
| }, |
There was a problem hiding this comment.
いらない予感?
これは next-auth のドキュメントがよくないよね
| async linkAccount(account) { | |
| const exists = await client.query( | |
| `SELECT EXISTS ( | |
| SELECT 1 | |
| FROM accounts | |
| WHERE "userId" = $1 AND provider = $2 AND "providerAccountId" = $3 | |
| );`, | |
| [account.userId, account.provider, account.providerAccountId], | |
| ); | |
| let sql: string; | |
| if (exists.rows[0].exists) { | |
| sql = ` | |
| update accounts set | |
| type = $3, | |
| access_token = $5, | |
| expires_at = $6, | |
| refresh_token = $7, | |
| id_token = $8, | |
| scope = $9, | |
| session_state = $10, | |
| token_type = $11 | |
| where "userId" = $1 AND provider = $2 AND "providerAccountId" = $4 | |
| returning | |
| id, | |
| "userId", | |
| provider, | |
| type, | |
| "providerAccountId", | |
| access_token, | |
| expires_at, | |
| refresh_token, | |
| id_token, | |
| scope, | |
| session_state, | |
| token_type | |
| `; | |
| } else { | |
| sql = ` | |
| insert into accounts | |
| ( | |
| "userId", | |
| provider, | |
| type, | |
| "providerAccountId", | |
| access_token, | |
| expires_at, | |
| refresh_token, | |
| id_token, | |
| scope, | |
| session_state, | |
| token_type | |
| ) | |
| values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) | |
| returning | |
| id, | |
| "userId", | |
| provider, | |
| type, | |
| "providerAccountId", | |
| access_token, | |
| expires_at, | |
| refresh_token, | |
| id_token, | |
| scope, | |
| session_state, | |
| token_type | |
| `; | |
| } | |
| const params = [ | |
| account.userId, | |
| account.provider, | |
| account.type, | |
| account.providerAccountId, | |
| account.access_token, | |
| account.expires_at, | |
| account.refresh_token, | |
| account.id_token, | |
| account.scope, | |
| account.session_state, | |
| account.token_type, | |
| ]; | |
| const result = await client.query(sql, params); | |
| return mapExpiresAt(result.rows[0]); | |
| }, |
There was a problem hiding this comment.
2回目以降のGoogleサインインでリフレッシュトークンを更新したいのでこんな感じになってます。
linkAccountじゃなくてもいいと思うけれども
src/auth.ts
Outdated
| adapter.linkAccount?.({ | ||
| ...account, | ||
| type: account.type as AdapterAccountType, | ||
| userId: adapterUser.id, | ||
| }); |
There was a problem hiding this comment.
この前に来る段階で next-auth が自動的に呼び出している(はず)
これは next-auth のドキュメントがよくないよね
| adapter.linkAccount?.({ | |
| ...account, | |
| type: account.type as AdapterAccountType, | |
| userId: adapterUser.id, | |
| }); |
There was a problem hiding this comment.
2回目以降のGoogleサインインだとlinkAccountが呼び出されなかったので明示的に呼び出してます。
There was a problem hiding this comment.
それは仕様なのよね
わかりにくいけど、そのプロバイダーで初めてログインしたときに作成された Accounts テーブルと、すでにあるかもしれない Users テーブルを結びつけるだけの操作なの(どちらのテーブルも linkAccount 呼び出し時には作成済み)
だから一度呼ばれるだけでいいのよ
There was a problem hiding this comment.
next-auth のコードみたらわかるようにはなってる(ドキュメントなし)
| prompt: 'consent', | ||
| access_type: 'offline', | ||
| response_type: 'code', |
There was a problem hiding this comment.
DB あるし、わざわざ毎回リフレッシュトークン発行してもらう必要ないような
https://authjs.dev/getting-started/providers/google#:~:text=If%20you%20need%20access%20to%20the%20RefreshToken%20or%20AccessToken%20for%20a%20Google%20account%20and%20you%20are%20not%20using%20a%20database%20to%20persist%20user%20accounts%2C%20this%20may%20be%20something%20you%20need%20to%20do.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
There was a problem hiding this comment.
Google only provides Refresh Token to an application the first time a user signs in.
って書いてるけど、この設定がないとRefresh Tokenが渡されなかった
https://developers.google.com/identity/openid-connect/openid-connect?hl=ja#exchangecode
refresh_token
(省略可)
このフィールドは、認証リクエストでaccess_type パラメータが offline に設定されている場合にのみ表示されます。詳しくは、更新トークンをご覧ください。
There was a problem hiding this comment.
DB あるし、わざわざ毎回リフレッシュトークン発行してもらう必要ないような https://authjs.dev/getting-started/providers/google#:~:text=If%20you%20need%20access%20to%20the%20RefreshToken%20or%20AccessToken%20for%20a%20Google%20account%20and%20you%20are%20not%20using%20a%20database%20to%20persist%20user%20accounts%2C%20this%20may%20be%20something%20you%20need%20to%20do.
nidkt.orgのサインインにGoogleを使うんだったら、リフレッシュトークンの発行は最初だけでいいと思うけど、
Googleサインインはユーザーがカレンダーをリンクしたい時とリンク先のアカウントを変更したい時に使われるだけなのでこれで良いと思ってる
Co-authored-by: Kawahara Shotaro <121674121+k-taro56@users.noreply.github.com>
Co-authored-by: Kawahara Shotaro <121674121+k-taro56@users.noreply.github.com>
Co-authored-by: Kawahara Shotaro <121674121+k-taro56@users.noreply.github.com>
NID-kt/bot-worker#77