//tips
//smart contract
先に作成したスクリプトの中身を確認していく。
export default NextAuth({の中で下記のようなcallbackが呼ばれているが
callbacks:{
async jwt({ token, user, account={}, profile, isNewUser }) {
これはAccess Tokenをブラウザに渡す際に、jwt callbackを呼ぶことで、トークンにデータを保管することができる。 session callbackを通してデータを渡す。
If you want to pass data such as an Access Token or User ID to the browser when using JSON Web Tokens, you can persist the data in the token when the jwt callback is called, then pass the data through to the browser in the session callback.
基本的な認証の流れを再度確認。6の部分に該当する動きか。
ユーザー→認証サーバー(認証情報)→ユーザー→アプリ→認証サーバー→アプリ(認証情報)→認証サーバ(認証トークン)→アプリ(認証トークン)→twitterなど認証先アプリ(ユーザーの情報提供)→アプリ→ブラウザ
1.ユーザーからのアクセス認証リクエストが認証サーバーへ
The application requests authorization to access service resources from the user
2.ユーザーが認証サーバからの確認を承認すると、アプリに認証情報が提供される
If the user authorized the request, the application receives an authorization grant
3.アプリのアクセスに対して、認証サーバから認証情報の確認
The application requests an access token from the authorization server (API) by presenting authentication of its own identity, and the authorization grant
4.認証されるとアプリに対して、サーバが、認証トークンを発行
If the application identity is authenticated and the authorization grant is valid, the authorization server (API) issues an access token to the application. Authorization is complete.
5.認証先アプリから情報の要求
The application requests the resource from the resource server (API) and presents the access token for authentication
6.トークンが有効であれば情報を獲得
If the access token is valid, the resource server (API) serves the resource to the application
アプリのサーバ側で情報の取得を行うため、それをブラウザに保管する動きが必要になるよう。
the jwt() callback is invoked before the session() callbackという流れはなんとなく分かっってきた。
この時理解が必要なJSON Web Tokens(JWT)とは、JSON形式で表現された認証情報などをURL文字列などとして安全に送受信できるよう符号化やデジタル署名の仕組みを規定した標準規格。電子署名により、改ざん検知でき、認証用のトークンなどで用いられる。認証やアクセス制御についての情報をJSON形式で記述し、一定の手順で符号化したtokenを生成することができる。
トークンはサーバとクライアントの間で送受信され、相手方で復号してデータを読み取る。
JWTは、3つのパーツで構成され、
ヘッダー(Base64文字列):JWTの署名検証を行うために必要な情報を格納するためのパート、jsonに変換できる。
ペイロード(Base64文字列):データ本体。システムが必要とするデータを任意に指定することができる。デコードすると下記のような状態になる。
{
"admin": true,
"name": "John Doe",
"sub": "1234567890"
}
署名(バイナリ文字列):トークンの作成者の本人証明に用いるデータで、ヘッダーとペイロードを符号化したものを連結し、本人の秘密鍵とともに署名アルゴリズムで計算することで生成される。受信側で対になる公開鍵を使って検証する。
Cryptoと同じ構造だと考えておけば良さそう。
https://techblog.yahoo.co.jp/advent-calendar-2017/jwt/
https://qiita.com/Naoto9282/items/8427918564400968bd2b
また、ユーザーがサインインしているかどうかはuseSession() を使うことでわかるようになる。
The useSession() React Hook in the NextAuth.js client is the easiest way to check if someone is signed in.
useSession() returns an object containing two values: data and statusで
when the session hasn't been fetched yet, data will undefined
in case it failed to retrieve the session, data will be null
in case of success, data will be Session.
となり、statusは "loading" | "authenticated" | "unauthenticated”のどれかになる。
これはまだわかりやすい。
問題なのは、jwtの引数とその戻り値がどこに使われるかで、これは/api/auth/にアクセスし、Twitterからfetchしたデータを引数にとり、それを加工したものが戻り値であることがわかっている。
callbacks:{
async jwt({ token, user, account={}, profile, isNewUser }) {
//https://next-auth.js.org/configuration/callbacks
//do something with the token
if(account.provider && !token[account.provider]){
token[account.provider]={};
}
if(account.accessToken){
token[account.provider].accessToken=account.accessToken;
}
if(account.refreshToken){
token[account.provider].refreshToken=account.refreshToken;
}
return token
}
},
このtokenの中身をもう少し理解したいので、ユーザーの流れを辿って、これらの要素が使われる部分を特定する。
まずはsessionの値自体が存在していないので、ユーザーはindex.jsのページに行き、renderの中のsign inボタンを押すことになる。これを押すと、signIn()が実行され、signinページに遷移させられる。これはnext-authの機能。
<p className={styles.description}>
{!session && <>
Not signed in <br/>
<button onClick={() => signIn()}>Sign in</button>
</>}
{session && <>
Signed in as {session.user.email} <br/>
<button onClick={() => signOut()}>Sign out</button>
</>}
</p>
そしてその際にproviderの情報からsigninボタンを自動生成する。