概要
Next.jsを使って,OAuth認証をするには,Next-Authというパッケージの利用がとても便利なのですが,デフォルトでライブラリに同梱されている認証プロバイダーは,老舗の認証ライブラリであるPassportなどに比べると,まだまだ限定的です.
しかし,だからといってNext-Authが使えないわけではありません.本稿では,Next-AuthのCustom Providerという仕組みを使って,2020年8月現在Built-in Providerには含まれていない,Microsoft Graph Authを実現する方法を紹介します.
アプリの登録
事前に,Azure Portalの「Azure Active Directory」→「App Registration」から,新規アプリの追加を行います.この時点で,Application Id (Client Id)が発行されます.
Secretは,「Certificates & Secrets」メニューから生成します.
OauthのRedirect URLの設定が必要になりますので,「Authentication」メニューから,開発用のURLであるhttp://localhost:3000/api/auth/callback/microsoft
を追加しておきましょう.
Scopeは必要なものを追加すればいいのですが,ここでは,User.Read
のみとして進めます.
.env.localの準備
登録が終われば,認証のための準備として,.env.local
ファイルに先ほどつくったAppのIDやSecretを書いておきます,
// .env.local
NEXTAUTH_URL=http://localhost:3000/
MS_CLIENT_ID=xxx
MS_CLIENT_SECRET=xxx
MS_OAUTH_SCOPE="user.read"
ずばり設定
以下の設定を,pages/api/auth/[...nextauth].js
のoptions.providers
に追加します.
{
id: "microsoft",
name: "Microsoft",
type: "oauth",
version: "2.0",
scope: process.env.MS_OAUTH_SCOPE!,
params: { grant_type: "authorization_code" },
accessTokenUrl: `https://login.microsoftonline.com/common/oauth2/v2.0/token`,
authorizationUrl: `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?response_type=code&response_mode=query`,
profileUrl: "https://graph.microsoft.com/v1.0/me",
profile: (profile: MicrosoftUser) => {
return {
id: profile.id ?? "",
email: profile.userPrincipalName ?? "",
name: profile.displayName ?? "",
image: "https://graph.microsoft.com/v1.0/me/photo/$value",
}
},
clientId: process.env.MS_CLIENT_ID!,
clientSecret: process.env.MS_CLIENT_SECRET!,
}
少しだけ補足しておくと,今回は,tenantIDをcommon
にすることで,MicrosoftアカウントおよびMicrosoft認証を使うすべてのwork/schoolアカウントでのログインを許可しています.詳しくは,こちら.
Reactでの利用
あとは,以下のようなボタンをどこかにおいておけば,
<button onClick={signIn}>Sign in</button>
クリック後に,/api/auth/signin
へと遷移し,プロバイダーとして,"Micosoft"の文字が出ているはずです.
無事に認証が終われば,Next-Authが提供する,useSession
フックを使って,ログインしているユーザーの情報を取得できます.
// pages/index.tsx
const Home: NextPage = () => {
const [session, loading] = useSession()
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<h1 className={styles.title}>Welcome to Next-Auth!</h1>
<>
{session && (
<>
Signed in as {session.user.email} <br />
<button onClick={signOut}>Sign out</button>
</>
)}
</>
</main>
</div>
)
}
export default Home
はい,それでは^^