iT邦幫忙

2023 iThome 鐵人賽

DAY 1
0
Modern Web

一些讓你看來很強的全端- trcp 伴讀系列 第 19

Day-019. 一些讓你看來很強的全端 TRPC 伴讀 -Next-Auth( GoogleProvider )

  • 分享至 

  • xImage
  •  

今天要來介紹 next-auth 設定~

正文介紹 (安裝)

開始前先安裝需要的套件

> npm install next-auth
> npm i @auth/prisma-adapter

那不知道讀者還有印象,在 day 17 介紹 github oauth 流程嗎?不記得沒關係這邊再放上圖給大家回覆印象~
https://ithelp.ithome.com.tw/upload/images/20231003/201456778htNs5McRq.png

那因為 next-auth 幫我們處理從登入換取 user access_token , 剩下的就是在 next-auth 中寫一個 api handler 拿取 user info

之後創建一個 ~src/api/auth/[...nextauth].ts 檔案,將以下的 code 貼上。

providers : 需要驗證第三方的平台,例如你要用 github 就用GithubProvider ,要用 Google 就用 GoogleProvider更多內容可以到 doc 查看設定。

import NextAuth, { AuthOptions } from "next-auth"
import GithubProvider from "next-auth/providers/github
export const authOptions: AuthOptions = {
  // Configure one or more authentication providers
  providers: [
    GithubProvider({
      clientId: process.env.GITHUB_ID as string,
      clientSecret: process.env.GITHUB_SECRET as string,
    }),
    // ...add more providers here
  ],
  secret: process.env.AUTH_SECRET,

}
export default NextAuth(authOptions)

secret : 因為 next-auth 需要 user 驗證的token 存到 cookie 中,那為了防止資安問題,會需要一組 secret ,對 user credentialshash 處理,以及對 cookie 生成的 signal 做加密並產生加密密鑰,這邊大概知道作用就好,主要是注意讀者需要設定secret

secret 可以是隨機亂數,這邊推薦讀者用 openssl 生成一個 base64 的隨機密鑰,

> openssl rand -base64 32
WNLr7tdndHgXLA2AaTzcY3a8in0qbWyMXOlG86iJUlQ=

之後把 SECRET 放到 .env

// .env
NEXTAUTH_SECRET="WNLr7tdndHgXLA2AaTzcY3a8in0qbWyMXOlG86iJUlQ="

GITHUB Provider setting

設定好 provider 後,接著需要設定 github OAuth Apps
https://ithelp.ithome.com.tw/upload/images/20231003/20145677qfng3U6Sx4.png

點選 OAuth Apps -> 點選 new OAuth App
https://ithelp.ithome.com.tw/upload/images/20231003/20145677V7ZBertDky.png

  • Application name: 專案名稱。
    * Homepage URL: 你的 web host 是什麼,因為你在開發模式所以這邊填 http://localhost:3000/
  • Authorization callback URL : 用來驗證/換取 tokencallback URL 因為適用 next-auth 所以是圖中設定,如果讀者有把 next-auth api host到其他地方記得之後要修改 callURL

設定好後就 Register
https://ithelp.ithome.com.tw/upload/images/20231003/20145677zh5ifrUZfK.png

接這吧 Client ID 複製起來放到 .env 中也就是 GITHUB_ID 的值。
揍一個則是 client secrets 第一次需要先生成,這個 secrets 記得保存好不要外洩,然後放到 .envGITHUB_SECRET 中。
https://ithelp.ithome.com.tw/upload/images/20231003/201456770G1aBbbXCg.png
https://ithelp.ithome.com.tw/upload/images/20231003/20145677qre9We1FJf.png

//.env
GITHUB_ID="your_ID"
GITHUB_SECRET="your_scret"

這邊一個貼心小提醒,有時候我們會不知道其他 providercallbackUrl 或是 signinUrl 是什麼不用擔心 next-auth 都有幫我們紀錄。

可以到 http://localhost:3000/api/auth/providers/github 中查看~

signinUrl : 則是sign in 會用到的 api route
callbackUrl : 則是sign in 成功後換取 user tokenapi route
https://ithelp.ithome.com.tw/upload/images/20231003/20145677UYFPua1ZEU.png

如果讀者有成功看到以上的 json response 代表你成功設定好 next-auth 摟~

測試 sign-in

接著我們簡單測試一下結果,到我們的 AuthForm 中,在 socialAction 呼叫 signIn


// ~src/components/AuthForm.tsx

import { signIn } from "next-auth/react"

//..
const socialAction = async (type: 'discord' | 'google' | 'github') => {
    try {

      setIsLoading(true)
      const callBack = await signIn(type)
    } catch (e) {
      console.log(e)
    } finally {
      setIsLoading(false)
    }
  }

如果是第一次登入會有以下的畫面,相信大家應該不陌生~
https://ithelp.ithome.com.tw/upload/images/20231003/20145677010NH9QbN1.png

接著驗證成功後會返回原本的頁面。

https://ithelp.ithome.com.tw/upload/images/20231003/20145677Y7wG4k2aGp.png

如果讀者不希望 user 每次用地方三方驗證都跳轉 Oauth page 的話,可以將redirect用成 false ,如此一來 next-auth 就會在背後幫你執行。

const callBack = await signIn(type, {
    redirect: false
})

接著 user 成功登入後我們需要將 user 換頁到user 頁面,而這麼專案我們會用幾天前用過的posts 頁面當作會員頁。

那這邊我會在 AuthFormuser 是否登入的判斷,當然如果需要用 provider 方式去包也 ok 這邊主要是簡單介紹概念~,日後會再寫一個 middle ware 驗證這件事~

我們可以透過 next-atuh 提供的 useSession 來檢查 user login info, 當session.statusauthenticated 時我們就去 posts 頁面。

// ~src/components/AuthForm.tsx

import {  useSession } from "next-auth/react"
//..
const session = useSession()

useEffect(() => {
    if (session.status === 'authenticated') {
      route.push('/posts')
    }
}, [session])

session 的內容如下,可以看到裡面包涵 user 簡單資料外,還有 expires 查看過期時間。
https://ithelp.ithome.com.tw/upload/images/20231003/20145677Fp23QfzIC7.png

Next-auth 中預設是30天過期,如果讀者想自行更改時效可以到 authOptions 設定 maxAge

export const authOptions: AuthOptions = {
 //..   
  session: {
    // default 2592000 // 30 days
    maxAge: 30 * 24 * 60 * 60
  }
}

如此一來我們就完成登入了~

https://ithelp.ithome.com.tw/upload/images/20231003/20145677jKDaNlTvLo.png
補充 一下還記得在AuthOptions 中的 secret 嗎,我們可以到 cookie中查看,如果有 next-auth.session-token 代表就是登入狀態摟~而且因為有 secret 幫忙做加密處理,也不用擔心 cookie外洩, 可以大大減少資安疑慮,甚至還有 next-auth.csrf-token 初步處理 csrf 問題~

https://ithelp.ithome.com.tw/upload/images/20231003/201456772P87y7Nmpi.png
今天簡單帶大家認識 next-auth 設定以及使用,這邊給讀者一個小挑戰除了 github 外,還有 discordgoogle 第三方登入沒有設定 OAuth app ,大家可以試著自己創創看,看能不能用在 Next-auth 中,筆者相信讀者們一定可以的~那如果設定上有什麼問題可以在底下提問,或是設定上有什麼心得也可以發表喔~

相關連結:

https://github.com/Danny101201/next_demo/tree/main

✅ 前端社群 :
https://lihi3.cc/kBe0Y


上一篇
Day-018. 一些讓你看來很強的全端 TRPC 伴讀 -Next-Auth(schema model)
下一篇
Day-020. 一些讓你看來很強的全端 TRPC 伴讀 -Next-Auth(CredentialsProvider)
系列文
一些讓你看來很強的全端- trcp 伴讀30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言