前回に続いてNextAuth.jsを用いてGitHubをバックエンドに持つWebアプリケーションを作成していきます.
内容
トークンでアクセスできる範囲をスコープとよび指定したスコープでアクセスできる範囲を限定できます. これをリポジトリの操作ができるように変更します. 次にSessionの内容を確認してアクセス・トークンを取得します.
GitHub認可プロバイダ
GitHub OAuth Appのスコープ
組み込みのGitHub認可プロバイダではuserに指定されています. userで許されるアクセス範囲は以下です.
Grants read/write access to profile info only. Note that this scope includes user:email and user:follow.
GitHub APIでリポジトリを操作するには物足りないですね. これをpublic_repoに変更しGitHub APIから操作できるようにします.
Limits access to public repositories. That includes read/write access to code, commit statuses, repository projects, collaborators, and deployment statuses for public repositories and organizations. Also required for starring public repositories.
GitHub認可プロバイダ型
GitHub認可プロバイダの型を見ると以下のようになっている.
type GitHub = (options: ProviderGitHubOptions) => GenericReturnConfig;
interface ProviderGitHubOptions {
clientId: string;
clientSecret: string;
scope?: string;
}
interface GenericReturnConfig {
[key: string]: any;
}
scopeはオプション型となっているだけなので指定すれば良いだけのようです.
Providers.GitHub({
scope: 'public_repo',
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET
}),
Access Tokenを探して
Sessionオブジェクト
公式の例では以下のようにaccessTokenが含まれているように見えます.
{
user: {
name: string,
email: string,
image: uri
},
accessToken: string,
expires: "YYYY-MM-DDTHH:mm:ss.SSSZ"
}
しかし実際に取得してみると存在しないことが分かります. ドキュメントには
// Note:
jwt
is automatically set totrue
if no database is specified.
と書いてあります. またコードを見るとデータベースのアダプターがない場合はjwtオプションがtrueに設定されるようになっています.
if (!adapter) {
sessionOptions.jwt = true
}
これらのことからoptionsのdatabaseの設定をコメント・アウトすれば良さそうです.
import NextAuth from 'next-auth'
import Providers from 'next-auth/providers'
const options = {
// Configure one or more authentication providers
providers: [
Providers.GitHub({
scope: 'public_repo',
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET
}),
// ...add more providers here
],
// A database is optional, but required to persist accounts in a database
database: process.env.DATABASE_URL,
}
export default (req, res) => NextAuth(req, res, options)
.env.localにDATABASE_URLを指定します.
DATABASE_URL=sqlite://localhost/:memory:?synchronize=true
synchronizeはTypeORMの設定らしいのですが, よく分かりません.
Setting synchronize makes sure your entities will be synced with the database, every time you run the application.
良く分からないのですがこれがないと動かないのでとりあえずtrueに設定しておくことにします.
最後に必要なsqlite3をインストールしておきます.
npm i sqlite3
セッション・オブジェクトを表示してaccessTokenが含まれていれば取得できています.
まとめ
ちょっと手こずりましたがアクセス・トークンも取れました. またわからない内容が多くて記事の内容が浅くなってしまいました.
次回はこれを使ってGitHub APIsにアクセスしていきたいと思います.
補足
synchronizeオプション
The synchronize option should not be used against production databases.
とありプロダクション用途ではこの設定は非推奨です. これはSQLiteもです.
SQLite is intended only for development / testing and not for production use.
今回はローカル上で動く個人のアプリなのでとりあえずこのまま使っていきたいと思います.
Further Reading
後で別の記事としてまとめようかと思っている項目です.
session.js
index.jsのこの部分とsession.jsを見るとSessionオブジェクトにaccessTokenを含むかを判断するロジックが理解できる.
Supports both JSON Web Tokens and database sessions
また
Can also be used without a database (e.g. OAuth + JWT)
JWT (JSON Web Token)
そもそもJWTとはどんなものなのか?
Introduction to JSON Web Tokens
[Next.js JWT authentication with React Hooks and Context API](https://www.jaygould.co.uk/2020-01-31-nextjs-auth-jwt-context-hooks/