Skip to content
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

Google認証とカレンダー連携 #98

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open

Google認証とカレンダー連携 #98

wants to merge 21 commits into from

Conversation

yuto-trd
Copy link
Member

@yuto-trd yuto-trd commented Aug 8, 2024

Copy link

vercel bot commented Aug 8, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
web ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 13, 2024 7:31pm

Copy link
Contributor

@k-taro56 k-taro56 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとう!! 😊😊😊😊😊
とってもたすかる!!

Comment on lines 145 to 231
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]);
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

いらない予感?
これは next-auth のドキュメントがよくないよね

Suggested change
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]);
},

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2回目以降のGoogleサインインでリフレッシュトークンを更新したいのでこんな感じになってます。
linkAccountじゃなくてもいいと思うけれども

src/auth.ts Outdated
Comment on lines 78 to 82
adapter.linkAccount?.({
...account,
type: account.type as AdapterAccountType,
userId: adapterUser.id,
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この前に来る段階で next-auth が自動的に呼び出している(はず)
これは next-auth のドキュメントがよくないよね

Suggested change
adapter.linkAccount?.({
...account,
type: account.type as AdapterAccountType,
userId: adapterUser.id,
});

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2回目以降のGoogleサインインだとlinkAccountが呼び出されなかったので明示的に呼び出してます。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

それは仕様なのよね

わかりにくいけど、そのプロバイダーで初めてログインしたときに作成された Accounts テーブルと、すでにあるかもしれない Users テーブルを結びつけるだけの操作なの(どちらのテーブルも linkAccount 呼び出し時には作成済み)
だから一度呼ばれるだけでいいのよ

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

next-auth のコードみたらわかるようにはなってる(ドキュメントなし)

src/auth.ts Outdated Show resolved Hide resolved
Comment on lines +176 to +178
prompt: 'consent',
access_type: 'offline',
response_type: 'code',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment was marked as off-topic.

Copy link
Member Author

@yuto-trd yuto-trd Aug 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 に設定されている場合にのみ表示されます。詳しくは、更新トークンをご覧ください。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

まじか

Copy link
Member Author

@yuto-trd yuto-trd Aug 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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サインインはユーザーがカレンダーをリンクしたい時とリンク先のアカウントを変更したい時に使われるだけなのでこれで良いと思ってる

src/utils/calendar/types.ts Outdated Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ほりゅう 🐉

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ほりゅう 🐉

src/utils/calendar/calendarService.ts Outdated Show resolved Hide resolved
src/utils/calendar/mapping.ts Outdated Show resolved Hide resolved
src/utils/calendar/mapping.ts Outdated Show resolved Hide resolved
yuto-trd and others added 2 commits August 12, 2024 03:54
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants